This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

#Load some useful libraries
library(limma)
library(DESeq2)
library(edgeR)
library(data.table)
library(tidyr)
library(magrittr)
library(tidyverse)
library(sjlabelled)
library(sjmisc)
library(ggplot2)
library(broom)
library(DataCombine)
#import data
countdf <- DropNA(read.csv(file = 'proteomics.csv'))
No Var specified. Dropping all NAs from the data frame.

0 rows dropped from the data frame because of missing values.
rownames(countdf) <- NULL
meta <- DropNA(read.csv(file = 'proteomics_metadata.csv'))
No Var specified. Dropping all NAs from the data frame.

0 rows dropped from the data frame because of missing values.
rownames(meta) <- NULL
anno <- DropNA(read.csv(file = 'proteomics_metadata_table.csv'))
No Var specified. Dropping all NAs from the data frame.

0 rows dropped from the data frame because of missing values.
rownames(anno) <- NULL
full <- DropNA(read.csv(file = 'proteomics_full.csv'))
No Var specified. Dropping all NAs from the data frame.

0 rows dropped from the data frame because of missing values.
rownames(full) <- NULL

#clean-up tables
#prepare for model
#make consistent index/column/label/ordering between tables/matrices
names(countdf)[1] <- 'name'
#countdf[countdf==0] <- 0.0000001
#countdf[countdf<0] <- 0.0000001
names(countdf) <- sapply(str_remove_all(names(countdf),"X"),"[") # remove added X's from PCI names
count_matrix <- countdf[,2:ncol(countdf)]
count_matrix <- as.matrix(count_matrix)
#count_matrix[,1] <- NULL
names(full) <- sapply(str_remove_all(colnames(full),"X"),"[")
names(count_matrix) <- sapply(str_remove_all(colnames(count_matrix),"X"),"[")
meta$sex <- factor(meta$sex)
full$sex <- factor(full$sex)
meta$bowel <- factor(as.numeric(factor(meta$bowel, levels = c(1,2,3,4), labels = c(1,2,3,4))))
full$bowel <- factor(as.numeric(factor(full$bowel, levels = c(1,2,3,4), labels = c(1,2,3,4))))
meta <- within(meta, bowel <- relevel(bowel, ref = 3))
full <- within(full, bowel <- relevel(bowel, ref = 3))
count_matrix
         01001621   01001661  01002192   01002471   01002885  01003555   01003757  01003758  01004037   01004350  01004551   01004575   01004596
         01005890   01005935  01006225   01007074   01007520   01008097  01008265  01008612   01008631   01009390   01009735  01010189   01010305
         01010353   01010869  01012428  01012516  01012545   01013541   01013762  01014138  01014816   01015440   01016929  01017180  01017741
        01017775  01018937  01019058   01019071   01020175  01020229  01021265  01022339   01022402  01022407   01022858   01023349   01023413
         01024256   01024456   01024630   01025234   01025263  01026607   01027404   01027470  01027537  01027696  01029036   01029221  01030956
         01031512   01031642   01032098   01032815  01033859  01034215  01034290   01034766   01035670   01035805  01036226  01037387   01037980
         01038044   01039187   01039289   01039498   01040030   01040480   01041616   01041867  01042050   01043932  01044249   01044589  01046903
         01047354  01047811   01047962   01048336   01048590   01049187   01049423   01049882  01050730  01051449   01051853  01052106   01052129
        01052191  01052215  01053273   01053715  01054467  01054605   01054953  01055203   01056512  01056539   01057091  01057221  01057494
         01057853  01058129  01058286  01058434   01058551  01059446  01061685   01062180   01062548   01062832   01063155   01063600   01063898
        01064166  01064217   01065495   01065558  01066219   01066842   01068049   01068336  01068343   01068688   01069664  01070356   01070706
         01073086   01074064   01074358  01074839   01074895   01074919  01075262   01075315  01075653   01075936  01076617  01076849   01077614
        01078359   01080714   01081740   01081870   01082166  01082219   01083356   01084760   01084848  01084936   01084981  01086028   01086260
         01087775   01089152  01089730  01090699   01090966  01090985   01091344   01092042   01092578   01093067  01095263   01095550   01095708
        01096598   01097616   01098111   01098582   01098662   01098708   01098954  01099022  01099707   01099807   01100090   01100093   01100301
        01100470  01100787  01101113   01101580   01101818  01103169   01104524  01104998   01105349   01106206  01106734   01107318   01107786
         01108839   01109152   01109311  01110511   01110652  01111390  01112052   01112213   01113056   01114773  01115185  01116419   01116698
         01117506   01117666   01118407  01118887  01119219  01119278  01119799  01121094  01121281  01121506  01124068   01124554   01124557
         01124640   01125510   01125762  01125820   01126088  01126228   01126385   01126611   01127076  01127950  01128019   01128104   01128604
        01129252  01129287  01129614   01130475  01131525  01131755   01131862  01133020   01133190   01133488   01133979   01134467  01134627
         01134852   01134952  01135208   01135229  01135434   01135564   01137439   01137764   01138494  01139462  01139724   01139766   01140117
         01140554   01140660  01141322   01141335   01141375  01141632   01142145  01142225   01142570   01142696   01143086  01144986  01145585
         01146647   01147280   01147647  01147722  01147944   01148342   01148826  01149234  01149874   01149887  01150088   01150133   01150256
         01150534  01150670   01151826  01152251   01153383   01154032  01154257  01154691  01154821   01154856   01154995  01155523  01155774
         01156249   01156974   01157208   01157232   01157578   01157765   01159150  01159198  01159216   01161402   01162879   01163159  01163255
        01163862   01164168   01165338   01165498   01166579   01166603   01167016  01167099  01167619  01167651   01167901  01168878   01169545
         01170158   01171221  01171818   01172696  01172809  01173245   01173930  01174400   01174530   01174804   01175004   01175083   01175269
        01175411   01175547  01176588   01177180   01178071   01178677   01179608   01179898   01179920  01180272   01180825  01181433   01181682
         01182274   01182288   01182576   01183340  01184006   01186457  01186567   01186997   01187657   01188084   01189255   01189640  01189651
         01191170   01191231  01192068   01192106  01192338   01192392   01193613   01194198   01194433   01194484  01195713  01195760  01196562
        01196748   01196776   01197219   01197268  01197529   01197763   01198460  01198770   01198896   01199042   01199304   01199448   01199581
        01199949   01200283   01200286   01200442  01200724   01201199   01201277  01202147   01202481  01202486   01202629   01203001   01203925
         01204364  01204451   01204665   01205026   01205849  01206131   01206460   01207423   01207801   01207810   01208014   01208152  01208285
         01209249  01209408   01209462   01210327  01211111  01212044   01214204   01214490  01214846   01215298   01215563   01216584   01216764
        01217376   01217679  01218073   01218722   01219514   01220660   01220747  01221266   01221452   01221476  01221559   01221615   01221688
        01222182  01222286  01222611  01223735  01223957  01224453   01224526  01224606   01225255   01226325   01226780   01226903  01227044
        01227858  01228251   01228476  01230087   01230333  01230573   01230961  01231502   01231615   01231638   01231872  01232606   01232614
         01233310  01233390   01233782   01234668  01236052   01236168   01236520   01236818  01238327   01238340   01238425   01238758  01239027
         01239160   01239686   01240429   01240762  01240947   01241681   01241841   01242341   01242582   01243433  01243762   01244248   01244421
         01245094  01247637  01248541   01248818   01248894  01249756   01250217   01250241   01250454   01251537   01252056   01252144  01252784
        01253011  01256739   01256840   01257335   01258294  01258737   01259522   01259658  01259738  01259834   01261412  01261654   01262152
         01262983   01263023   01263493   01264795   01265498   01265757  01266086  01267255   01267393   01267420   01268471   01268568   01268746
         01268785   01270078   01270317   01270608  01271411   01272145   01272380   01273646   01274049   01274423   01274979   01275666   01275996
         01277016   01277584  01277761   01277837   01277838   01278177   01278714   01279158   01279889   01280219   01280637  01282093   01282698
        01283684   01283804  01284672   01285204  01285575   01285674  01285871  01286296  01286616   01286934  01286951   01287002  01287040
         01287991   01288413  01289179   01289365   01289651   01290444   01290685   01291492   01293694   01294222   01294594  01295153  01295377
        01295520   01295702   01296751  01297012  01298401   01298856   01299311  01299519   01300928   01301558   01301843  01302154   01302610
         01303423   01304044   01304906   01304992   01305376   01306236  01306720   01307131  01307158  01307371   01308508   01308730  01308800
         01309498  01309779   01310126   01310175   01310261  01310389  01311144   01311318   01311478   01311579  01311895   01312483   01312666
         01312792   01313082   01313668   01313904   01314140   01314788   01315038  01315327   01315770   01316569   01317285  01317702   01317813
         01318417  01319136   01319649   01319761  01320932   01321418   01321719   01321726  01321820   01321856   01322694   01323045  01323399
         01323640  01323952  01324141   01324463   01325310   01325488   01327998   01328835   01329753   01330626   01330925  01331422   01331474
         01331668   01331916  01331919   01333624   01333878  01334323  01334416  01334918   01334958   01335458   01335521   01336320   01336644
         01336769  01337343   01337814   01337835   01338370   01338813   01340139   01341810   01342346  01342354   01344468   01345091   01345295
         01345440   01346074  01346645  01349077   01349596   01349735   01349868   01350228  01351892   01352867   01353189  01353572  01354461
        01354787   01354879  01354930   01355010   01355342  01355514  01355617  01355791   01356466  01357653   01357953   01358815  01358940
         01359817   01359989  01360278   01360318   01360677   01361259   01361414  01361790   01362364   01362687  01363795   01364126  01364192
         01364721  01365052  01365832   01366208   01366706  01366783   01367738  01367896  01367974   01368088   01368213  01368780   01369634
         01370236   01370608   01371698   01371934   01372136   01372590  01373046  01374010   01374127   01374976   01375514  01376324   01377852
        01378031   01378108  01378660   01378885  01380424   01381144   01381548   01382653   01382823   01384009  01384259  01384536   01385380
        01386387   01386550   01386776   01386876   01387787  01388193   01388232   01388366   01389526  01390496   01390540   01391396   01392716
         01392841  01393107  01393734  01394181   01394556   01395120  01395563  01395662   01395750   01395906   01396584   01396601  01397710
         01397998  01398191   01398959   01399040  01399383   01399987   01400682   01401259  01401611   01401924  01402249   01403452   01404254
        01404344  01404357   01405352  01405518   01405558   01405967  01407492   01409276  01409471  01410286  01411311  01411551  01411874
         01411965   01412088   01412110   01412199  01414715  01414861   01415267  01416835  01417740  01419702  01419731   01420162   01421501
         01422755   01423895   01425137   01425460   01426287  01426848  01427224  01427331   01428031   01428273  01429795  01431847   01432148
        01433659   01433801   01434051   01434290  01434465   01434970   01435210   01436011  01436147  01436826  01436873  01438254   01440274
         01440344  01440882   01441047   01441388  01442539   01443291  01443715   01443984   01444005  01445121   01445177  01445418   01446014
        01446768  01446781   01446975   01447446  01448060   01448663  01449363  01449403  01449816  01450565   01451049  01451795  01452282
        01453251   01453593  01453805   01454929   01455153   01455437   01456065   01456773  01457096  01457354  01457675  01457928   01458377
        01458643   01459084   01459367   01460209  01460589  01460874   01461000   01462010   01463203   01463442  01463928   01464386  01465504
         01465880   01466144  01466897  01467082   01467301  01468509  01469251   01469484   01471106  01471283   01471958   01472130   01472282
         01473368  01474611   01474832   01475942  01476994  01477610   01478283   01478460  01478952  01479699   01480898   01481827   01481963
         01482624   01482696   01483006   01483595   01483880   01484509   01484820  01484900   01485116   01486207   01486356   01487038   01487379
        01487429  01487447   01487936  01489017  01489961   01491050   01491245   01491438  01492075   01492335  01492554  01493928   01494796
        01495022  01496084  01496511   01497137  01497187  01497207   01497564   01498008   01498133  01498419  01498803   01498819  01499133
        01500041   01500706   01500905   01501052  01501394   01502061   01502166   01502372  01502665  01502955  01503152   01503991   01504004
        01504715   01504947   01505154   01505234   01505239   01506485  01507346  01507406   01507409  01507725   01507901  01508587  01509123
         01509755  01509874  01510391  01512568  01512651   01512820   01512873   01513501   01513951   01513993   01514506   01514916  01515817
         01516039  01516471   01516875   01517032  01518082  01519454  01520235   01520548   01521943  01522368   01522520   01523020  01523098
         01523105  01523585  01523727   01524770   01524948   01524993   01525542   01525582   01525622  01526026   01526106   01526266   01526319
        01526851   01527506   01527984   01529564  01529986   01530013   01530183   01530776  01531584  01531672  01531930   01532308   01532385
         01533482   01534594  01535305   01535696   01537373   01537421   01537685   01537829  01538052   01538140   01538499  01538834   01539159
         01539774  01540348   01540773   01542101   01543171   01543234   01543273   01544466  01546490   01546772   01547098  01547347  01547484
         01547734   01548010  01548252  01548440   01548550  01549121  01549546   01549572   01549682  01549724  01550307   01550935   01551074
        01552128   01552328   01552413   01552705   01553636  01554773  01555036   01555060  01556165   01556245  01556246   01556738  01556883
         01557175  01557456   01558096  01558147   01558664   01558921   01558931   01559746  01560264  01560665   01561118   01561429  01562330
        01563052   01563188   01564492  01564625   01564778  01565016   01565064   01565346   01565368   01565759   01566332   01566704   01567520
         01567650   01567746   01567970  01568163  01568473  01568974  01569630   01569807  01570500  01571162   01571964   01572339   01572546
         01572624   01573608  01573785   01574176  01574299   01574520   01574670   01574852  01574898   01575100   01575601   01576069   01576258
        01576364   01576520  01578874   01579217   01579241   01579937   01580127  01580290   01580815   01581390   01581712   01582628   01582722
        01584311   01585888   01586010   01586396   01586834  01587997  01588280  01589512  01590058   01590178   01590753   01591420   01593246
        01593251   01593473   01593831   01593904   01594166   01594415   01594640   01594862   01595697   01596232  01596320   01596440   01596522
         01596575   01596979   01597176  01597908  01598859   01599287   01599865  01599873  01600334   01600512  01600788  01600866   01601230
        01601767  01602144   01602320   01602518  01603266   01603339   01604016   01605675   01605949   01606409  01606532   01608846  01609204
         01609282   01609415   01610044   01610133   01610717  01610725  01610891   01611163   01611286  01613457  01613582   01615426   01615482
        01615761  01616824  01616854   01617024   01617608   01618533  01618870   01619062  01619307  01619551   01620794   01621465   01621998
         01622490  01622816  01622891   01623996   01625865   01626742   01627360  01627457   01627542   01627988   01628226   01628231   01628648
         01629336   01629792   01629802  01630028  01630552   01631397   01632022  01632062   01632380  01632388   01632550   01632988  01633002
         01634101   01634198   01634953  01634983   01635231  01635305   01635480   01635798   01635970  01636270  01636818   01636879  01637570
        01637745   01638382   01638800  01639191   01639404  01639449  01640776   01641029  01641642   01642371  01642495   01642695   01643165
        01643211   01643414   01643636  01643686   01644608   01645027  01645393   01645421  01645507   01646283  01646388   01646464   01647640
         01647993   01649083   01649532   01650330   01650513  01651008   01651282   01651337  01651544   01651707  01652307   01652669  01652804
        01653010   01653105  01653688   01653978   01654763   01654844  01655416   01655834  01656771   01657311   01657488   01658403   01658910
         01658967   01660086   01660139   01660427   01663136   01663468   01664068  01664924   01665084   01665528   01665576   01665663   01666658
         01667395  01668075   01668237   01668699   01669850   01669855  01670861  01671260  01673066  01673539   01673643   01673724   01674089
        01674506   01675402  01677181   01677762   01679455  01680556  01681307   01681502   01681574   01681890   01682023  01682186   01684342
         01685714   01685762   01686104   01688437   01688579  01689987   01691639   01691779   01693046   01693172   01693390   01693506   01697686
         01699357  01699486  01699509   01700903   01701075   01701078   01701400  01701471   01701905   01702402  01702792   01703226  01703603
        01703920   01704905   01706279  01706568   01706989   01707148  01707649  01709003   01709242  01709473  01710221  01710811  01710995
         01711014   01711751   01712377   01712477  01712878   01713006  01713322  01714348   01716062  01716276   01717373   01717400   01717633
         01717861   01718526   01719258  01719307   01719407   01719665  01720029   01720720   01721067  01721559   01722208   01723475   01723869
         01724289   01725364   01725958   01726317   01726684   01727114   01728253  01728293  01728390   01728702  01728957   01729301   01730641
        01731363   01731711  01733141  01733867  01734469   01735802   01735977   01736024  01736530   01737230   01737897   01738682   01739253
         01740524  01741283  01741614   01742358  01743072   01743082   01743982   01744818   01744990   01745903   01746653  01746677  01746733
        01746899  01747121   01747127   01747753   01748797   01749732   01752720   01752804  01752904   01754198   01754296   01755760   01755996
         01756172   01757224   01757541   01758362   01758650   01759047  01759149   01759424   01759793   01760704   01760799   01761910   01763581
         01764159   01764768  01765235  01765390   01765746   01766077   01767516  01767620  01767765   01767810   01769358   01769659  01769675
         01770063   01770465   01770470  01770698   01770742   01772400  01774268   01774351   01775397   01775444   01775580  01775747  01777122
         01777300   01777671  01778086   01778402   01778710  01778969  01779428   01779613   01779703   01779914   01780145   01780876  01780900
        01781027  01781229   01781248  01781459  01782034   01782110   01783121   01784220  01784963  01785261  01785495   01787022  01787060
         01787311   01788170   01788725   01788805   01789415  01789593  01789705   01790494   01790845  01790891   01791313   01793432  01793692
         01794557  01794702  01795699   01795962   01796013   01796668   01796738   01798094   01798171   01798457  01798624   01798631   01799122
        01799627   01800273   01801917  01802021   01802163   01802964  01803225   01803627   01804135   01804284  01806149  01806152  01807115
         01807510   01808734  01809016   01812156   01814069   01814335   01814396   01814606   01815158   01815820   01816988  01817283   01817289
        01819087  01819282   01819787   01820163  01820666   01820710  01821427  01821454   01821552  01822309   01822602   01822702  01823769
         01823862   01823865   01825216   01826852   01826912   01828968   01829590   01829852   01832213   01832310   01832962  01834243   01834594
         01834768   01835198  01835383   01835619   01835941   01836500   01837160   01837244  01838254  01840056   01840662   01840834  01841123
         01842136   01842802  01842820  01843011   01843022  01843404   01843591   01843887   01844983   01845430  01846239  01846975   01848246
         01849109   01849730   01849944  01850412   01851966   01852207  01852337   01852342   01852965   01853112   01853524   01853575  01853660
        01854068   01854235   01854294  01855359   01856180   01856361   01857729   01858442   01858704   01858873  01858976  01859111   01859360
         01859809  01859929  01859995   01860248  01860486   01860772  01861175  01861775   01862266   01863420   01863617   01864232   01864390
         01864964   01865441  01865446   01866098   01866327   01866472   01866618  01867779   01868438   01869208  01869613   01870183  01870642
         01870822  01871379   01871388   01872393   01872692   01873155  01873627   01874023   01874114  01874421  01875465   01875466  01875589
         01876881   01877237  01877498   01878860   01879129   01879709  01879734   01880385   01882045   01883201   01883918   01884560   01884654
         01884763   01884765  01884834  01886527   01887050  01887154   01887756  01888706   01888966  01890552   01891531   01891897   01892350
        01892834   01893068   01893267   01894980   01897097   01897103   01898332   01898793   01899131   01899270   01899508   01900174   01900684
         01901038   01901814   01902049   01902313   01902621  01903562   01903748   01905229   01905932   01906832  01906856   01907066   01907416
        01907575  01907913   01908830  01909024   01909532   01909625   01909807   01910034   01911124   01911172  01911364   01911370  01912726
         01912853   01913481   01913933  01914451   01915036   01915440   01916045  01916479   01916558   01917148   01917153  01917395  01918227
        01918540   01918943  01918980   01918983   01919756   01919987   01920535   01920869  01921596   01922612   01922780  01923555   01924106
         01924225   01925138   01925174   01925178   01925800   01926181   01926351  01926397   01926537   01926705  01927157  01927181   01927185
         01927208   01928201   01929506   01929517   01930116  01930547  01930731  01930960   01931778   01931849   01931898   01932120  01932384
        01932611  01932693   01933205   01933291   01934177   01934222  01935644   01935829  01935930   01936132   01937405   01937921   01938378
        01938606  01939058  01939189  01939555   01940575   01940618   01941086  01941134   01941857  01942853  01943201   01943712  01944942
         01945564   01946056   01946852   01947387  01947733   01948018   01948580   01948634   01949838   01950342   01952180  01952330   01953116
        01953398   01954001  01954492  01954615   01954804   01954947  01955210   01955250  01955427   01955611   01956344   01958214   01958339
         01959030   01959080   01959804  01959844   01959943   01960296  01960682   01960736   01960876  01962038   01962253   01962385  01962646
        01963140   01963243  01963556   01964190  01964339  01965364   01965921   01965975   01966606   01966838   01968285  01968623  01969364
        01969821  01970438   01971060  01971659   01971921  01972000   01972700   01974110  01974625   01974833   01975030   01975130   01975702
         01976404   01976567  01980181  01980311   01980444  01980931  01981511  01982074   01982352   01982907   01983318   01984058   01984497
         01984762   01984864   01984952   01985328   01985884   01986408  01987388  01987914  01988559  01988631  01989393   01989933   01990047
        01990311   01992522   01993866   01994088  01994108   01994373  01994483   01995018  01995109  01995589   01995656   01997414  01997759
        01997826   01997940   01998370   01998451   01998999  01999351   H344502   H409129   H460562   H794171
 [ reached getOption("max.print") -- omitted 274 rows ]
attr(,"names")
   [1] "01001621" "01001661" "01002192" "01002471" "01002885" "01003555" "01003757" "01003758" "01004037" "01004350" "01004551" "01004575" "01004596"
  [14] "01005890" "01005935" "01006225" "01007074" "01007520" "01008097" "01008265" "01008612" "01008631" "01009390" "01009735" "01010189" "01010305"
  [27] "01010353" "01010869" "01012428" "01012516" "01012545" "01013541" "01013762" "01014138" "01014816" "01015440" "01016929" "01017180" "01017741"
  [40] "01017775" "01018937" "01019058" "01019071" "01020175" "01020229" "01021265" "01022339" "01022402" "01022407" "01022858" "01023349" "01023413"
  [53] "01024256" "01024456" "01024630" "01025234" "01025263" "01026607" "01027404" "01027470" "01027537" "01027696" "01029036" "01029221" "01030956"
  [66] "01031512" "01031642" "01032098" "01032815" "01033859" "01034215" "01034290" "01034766" "01035670" "01035805" "01036226" "01037387" "01037980"
  [79] "01038044" "01039187" "01039289" "01039498" "01040030" "01040480" "01041616" "01041867" "01042050" "01043932" "01044249" "01044589" "01046903"
  [92] "01047354" "01047811" "01047962" "01048336" "01048590" "01049187" "01049423" "01049882" "01050730" "01051449" "01051853" "01052106" "01052129"
 [105] "01052191" "01052215" "01053273" "01053715" "01054467" "01054605" "01054953" "01055203" "01056512" "01056539" "01057091" "01057221" "01057494"
 [118] "01057853" "01058129" "01058286" "01058434" "01058551" "01059446" "01061685" "01062180" "01062548" "01062832" "01063155" "01063600" "01063898"
 [131] "01064166" "01064217" "01065495" "01065558" "01066219" "01066842" "01068049" "01068336" "01068343" "01068688" "01069664" "01070356" "01070706"
 [144] "01073086" "01074064" "01074358" "01074839" "01074895" "01074919" "01075262" "01075315" "01075653" "01075936" "01076617" "01076849" "01077614"
 [157] "01078359" "01080714" "01081740" "01081870" "01082166" "01082219" "01083356" "01084760" "01084848" "01084936" "01084981" "01086028" "01086260"
 [170] "01087775" "01089152" "01089730" "01090699" "01090966" "01090985" "01091344" "01092042" "01092578" "01093067" "01095263" "01095550" "01095708"
 [183] "01096598" "01097616" "01098111" "01098582" "01098662" "01098708" "01098954" "01099022" "01099707" "01099807" "01100090" "01100093" "01100301"
 [196] "01100470" "01100787" "01101113" "01101580" "01101818" "01103169" "01104524" "01104998" "01105349" "01106206" "01106734" "01107318" "01107786"
 [209] "01108839" "01109152" "01109311" "01110511" "01110652" "01111390" "01112052" "01112213" "01113056" "01114773" "01115185" "01116419" "01116698"
 [222] "01117506" "01117666" "01118407" "01118887" "01119219" "01119278" "01119799" "01121094" "01121281" "01121506" "01124068" "01124554" "01124557"
 [235] "01124640" "01125510" "01125762" "01125820" "01126088" "01126228" "01126385" "01126611" "01127076" "01127950" "01128019" "01128104" "01128604"
 [248] "01129252" "01129287" "01129614" "01130475" "01131525" "01131755" "01131862" "01133020" "01133190" "01133488" "01133979" "01134467" "01134627"
 [261] "01134852" "01134952" "01135208" "01135229" "01135434" "01135564" "01137439" "01137764" "01138494" "01139462" "01139724" "01139766" "01140117"
 [274] "01140554" "01140660" "01141322" "01141335" "01141375" "01141632" "01142145" "01142225" "01142570" "01142696" "01143086" "01144986" "01145585"
 [287] "01146647" "01147280" "01147647" "01147722" "01147944" "01148342" "01148826" "01149234" "01149874" "01149887" "01150088" "01150133" "01150256"
 [300] "01150534" "01150670" "01151826" "01152251" "01153383" "01154032" "01154257" "01154691" "01154821" "01154856" "01154995" "01155523" "01155774"
 [313] "01156249" "01156974" "01157208" "01157232" "01157578" "01157765" "01159150" "01159198" "01159216" "01161402" "01162879" "01163159" "01163255"
 [326] "01163862" "01164168" "01165338" "01165498" "01166579" "01166603" "01167016" "01167099" "01167619" "01167651" "01167901" "01168878" "01169545"
 [339] "01170158" "01171221" "01171818" "01172696" "01172809" "01173245" "01173930" "01174400" "01174530" "01174804" "01175004" "01175083" "01175269"
 [352] "01175411" "01175547" "01176588" "01177180" "01178071" "01178677" "01179608" "01179898" "01179920" "01180272" "01180825" "01181433" "01181682"
 [365] "01182274" "01182288" "01182576" "01183340" "01184006" "01186457" "01186567" "01186997" "01187657" "01188084" "01189255" "01189640" "01189651"
 [378] "01191170" "01191231" "01192068" "01192106" "01192338" "01192392" "01193613" "01194198" "01194433" "01194484" "01195713" "01195760" "01196562"
 [391] "01196748" "01196776" "01197219" "01197268" "01197529" "01197763" "01198460" "01198770" "01198896" "01199042" "01199304" "01199448" "01199581"
 [404] "01199949" "01200283" "01200286" "01200442" "01200724" "01201199" "01201277" "01202147" "01202481" "01202486" "01202629" "01203001" "01203925"
 [417] "01204364" "01204451" "01204665" "01205026" "01205849" "01206131" "01206460" "01207423" "01207801" "01207810" "01208014" "01208152" "01208285"
 [430] "01209249" "01209408" "01209462" "01210327" "01211111" "01212044" "01214204" "01214490" "01214846" "01215298" "01215563" "01216584" "01216764"
 [443] "01217376" "01217679" "01218073" "01218722" "01219514" "01220660" "01220747" "01221266" "01221452" "01221476" "01221559" "01221615" "01221688"
 [456] "01222182" "01222286" "01222611" "01223735" "01223957" "01224453" "01224526" "01224606" "01225255" "01226325" "01226780" "01226903" "01227044"
 [469] "01227858" "01228251" "01228476" "01230087" "01230333" "01230573" "01230961" "01231502" "01231615" "01231638" "01231872" "01232606" "01232614"
 [482] "01233310" "01233390" "01233782" "01234668" "01236052" "01236168" "01236520" "01236818" "01238327" "01238340" "01238425" "01238758" "01239027"
 [495] "01239160" "01239686" "01240429" "01240762" "01240947" "01241681" "01241841" "01242341" "01242582" "01243433" "01243762" "01244248" "01244421"
 [508] "01245094" "01247637" "01248541" "01248818" "01248894" "01249756" "01250217" "01250241" "01250454" "01251537" "01252056" "01252144" "01252784"
 [521] "01253011" "01256739" "01256840" "01257335" "01258294" "01258737" "01259522" "01259658" "01259738" "01259834" "01261412" "01261654" "01262152"
 [534] "01262983" "01263023" "01263493" "01264795" "01265498" "01265757" "01266086" "01267255" "01267393" "01267420" "01268471" "01268568" "01268746"
 [547] "01268785" "01270078" "01270317" "01270608" "01271411" "01272145" "01272380" "01273646" "01274049" "01274423" "01274979" "01275666" "01275996"
 [560] "01277016" "01277584" "01277761" "01277837" "01277838" "01278177" "01278714" "01279158" "01279889" "01280219" "01280637" "01282093" "01282698"
 [573] "01283684" "01283804" "01284672" "01285204" "01285575" "01285674" "01285871" "01286296" "01286616" "01286934" "01286951" "01287002" "01287040"
 [586] "01287991" "01288413" "01289179" "01289365" "01289651" "01290444" "01290685" "01291492" "01293694" "01294222" "01294594" "01295153" "01295377"
 [599] "01295520" "01295702" "01296751" "01297012" "01298401" "01298856" "01299311" "01299519" "01300928" "01301558" "01301843" "01302154" "01302610"
 [612] "01303423" "01304044" "01304906" "01304992" "01305376" "01306236" "01306720" "01307131" "01307158" "01307371" "01308508" "01308730" "01308800"
 [625] "01309498" "01309779" "01310126" "01310175" "01310261" "01310389" "01311144" "01311318" "01311478" "01311579" "01311895" "01312483" "01312666"
 [638] "01312792" "01313082" "01313668" "01313904" "01314140" "01314788" "01315038" "01315327" "01315770" "01316569" "01317285" "01317702" "01317813"
 [651] "01318417" "01319136" "01319649" "01319761" "01320932" "01321418" "01321719" "01321726" "01321820" "01321856" "01322694" "01323045" "01323399"
 [664] "01323640" "01323952" "01324141" "01324463" "01325310" "01325488" "01327998" "01328835" "01329753" "01330626" "01330925" "01331422" "01331474"
 [677] "01331668" "01331916" "01331919" "01333624" "01333878" "01334323" "01334416" "01334918" "01334958" "01335458" "01335521" "01336320" "01336644"
 [690] "01336769" "01337343" "01337814" "01337835" "01338370" "01338813" "01340139" "01341810" "01342346" "01342354" "01344468" "01345091" "01345295"
 [703] "01345440" "01346074" "01346645" "01349077" "01349596" "01349735" "01349868" "01350228" "01351892" "01352867" "01353189" "01353572" "01354461"
 [716] "01354787" "01354879" "01354930" "01355010" "01355342" "01355514" "01355617" "01355791" "01356466" "01357653" "01357953" "01358815" "01358940"
 [729] "01359817" "01359989" "01360278" "01360318" "01360677" "01361259" "01361414" "01361790" "01362364" "01362687" "01363795" "01364126" "01364192"
 [742] "01364721" "01365052" "01365832" "01366208" "01366706" "01366783" "01367738" "01367896" "01367974" "01368088" "01368213" "01368780" "01369634"
 [755] "01370236" "01370608" "01371698" "01371934" "01372136" "01372590" "01373046" "01374010" "01374127" "01374976" "01375514" "01376324" "01377852"
 [768] "01378031" "01378108" "01378660" "01378885" "01380424" "01381144" "01381548" "01382653" "01382823" "01384009" "01384259" "01384536" "01385380"
 [781] "01386387" "01386550" "01386776" "01386876" "01387787" "01388193" "01388232" "01388366" "01389526" "01390496" "01390540" "01391396" "01392716"
 [794] "01392841" "01393107" "01393734" "01394181" "01394556" "01395120" "01395563" "01395662" "01395750" "01395906" "01396584" "01396601" "01397710"
 [807] "01397998" "01398191" "01398959" "01399040" "01399383" "01399987" "01400682" "01401259" "01401611" "01401924" "01402249" "01403452" "01404254"
 [820] "01404344" "01404357" "01405352" "01405518" "01405558" "01405967" "01407492" "01409276" "01409471" "01410286" "01411311" "01411551" "01411874"
 [833] "01411965" "01412088" "01412110" "01412199" "01414715" "01414861" "01415267" "01416835" "01417740" "01419702" "01419731" "01420162" "01421501"
 [846] "01422755" "01423895" "01425137" "01425460" "01426287" "01426848" "01427224" "01427331" "01428031" "01428273" "01429795" "01431847" "01432148"
 [859] "01433659" "01433801" "01434051" "01434290" "01434465" "01434970" "01435210" "01436011" "01436147" "01436826" "01436873" "01438254" "01440274"
 [872] "01440344" "01440882" "01441047" "01441388" "01442539" "01443291" "01443715" "01443984" "01444005" "01445121" "01445177" "01445418" "01446014"
 [885] "01446768" "01446781" "01446975" "01447446" "01448060" "01448663" "01449363" "01449403" "01449816" "01450565" "01451049" "01451795" "01452282"
 [898] "01453251" "01453593" "01453805" "01454929" "01455153" "01455437" "01456065" "01456773" "01457096" "01457354" "01457675" "01457928" "01458377"
 [911] "01458643" "01459084" "01459367" "01460209" "01460589" "01460874" "01461000" "01462010" "01463203" "01463442" "01463928" "01464386" "01465504"
 [924] "01465880" "01466144" "01466897" "01467082" "01467301" "01468509" "01469251" "01469484" "01471106" "01471283" "01471958" "01472130" "01472282"
 [937] "01473368" "01474611" "01474832" "01475942" "01476994" "01477610" "01478283" "01478460" "01478952" "01479699" "01480898" "01481827" "01481963"
 [950] "01482624" "01482696" "01483006" "01483595" "01483880" "01484509" "01484820" "01484900" "01485116" "01486207" "01486356" "01487038" "01487379"
 [963] "01487429" "01487447" "01487936" "01489017" "01489961" "01491050" "01491245" "01491438" "01492075" "01492335" "01492554" "01493928" "01494796"
 [976] "01495022" "01496084" "01496511" "01497137" "01497187" "01497207" "01497564" "01498008" "01498133" "01498419" "01498803" "01498819" "01499133"
 [989] "01500041" "01500706" "01500905" "01501052" "01501394" "01502061" "01502166" "01502372" "01502665" "01502955" "01503152" "01503991"
 [ reached getOption("max.print") -- omitted 546726 entries ]
countdf
meta
anno
full
# Design linear regression models using lmFit and eBayes with LIMMA
# This code adapted from Christian Diener, PhD:
design <- model.matrix(~bowel + sex + age + BMI_CALC + eGFR, meta) # Covariates: sex, age, BMI
#dge <- DGEList(counts=count_matrix)  # Where `count_matrix` is the matrix mentioned above
#dge <- calcNormFactors(count_matrix)  # Normalize the matrix (this step only for CORNCOB/microbiome data)
#logCPM <- cpm(dge, log=FALSE)  # Takes the log of the data
fit <- lmFit(count_matrix, design)  # Fits the model for all metabolites
fit <- eBayes(fit)  # Stabilizes the variances
fit
#Pre-process for plotting:
#Get results table for Constipation coefficient relative to High Normal BMF:
re_const <- topTable(fit, coef = 2, genelist = anno, sort="p", number="none")  # Select the significant models by coefficient 2

indices <- match(rownames(re_const), rownames(anno)) # associate column of protein names with index of protein
re_const[1] <- anno$name[indices] # associate the protein names with the protein indices
re_const <- dplyr::inner_join(anno, re_const, by = intersect(names(anno),names(re_const))) #combine anno and re dfs by intersection of protein values
p_const <- re_const[re_const$adj.P.Val < 0.05,] # create df of just significant adj P value results
p_const <- p_const[order(p_const$adj.P.Val),] # order by adj P value
p_const <- p_const[,c('logFC','B','adj.P.Val','name','panel','uniprot','gene_name','gene_description','P.Value')] # keep only desired columns

#Pre-process for plotting:
#Get results table for Low Normal coefficient relative to High Normal BMF:
re_low <- topTable(fit, coef = 3, genelist = anno, sort="p", number="none")  # Select the significant models by coefficient 3

indices <- match(rownames(re_low), rownames(anno)) # associate column of protein names with index of protein
re_low[1] <- anno$name[indices] # associate the protein names with the protein indices
re_low <- dplyr::inner_join(anno, re_low, by = intersect(names(anno),names(re_low))) #combine anno and re dfs by intersection of protein values
p_low <- re_low[re_low$adj.P.Val < 0.05,] # create df of just significant adj P value results
p_low <- p_low[order(p_low$adj.P.Val),] # order by adj P value
p_low <- p_low[,c('logFC','B','adj.P.Val','name','panel','uniprot','gene_name','gene_description','P.Value')] # keep only desired columns

#Pre-process for plotting:
#Get results table for Diarrhea coefficient relative to High Normal BMF:
re_diarrhea <- topTable(fit, coef = 4, genelist = anno, sort="p", number="none")  # Select the significant models by coefficient 4

indices <- match(rownames(re_diarrhea), rownames(anno)) # associate column of protein names with index of protein
re_diarrhea[1] <- anno$name[indices] # associate the protein names with the protein indices
re_diarrhea <- dplyr::inner_join(anno, re_diarrhea, by = intersect(names(anno),names(re_diarrhea))) #combine anno and re dfs by intersection of protein values
p_diarrhea <- re_diarrhea[re_diarrhea$adj.P.Val < 0.05,] # create df of just significant adj P value results
p_diarrhea <- p_diarrhea[order(p_diarrhea$adj.P.Val),] # order by adj P value
p_diarrhea <- p_diarrhea[,c('logFC','B','adj.P.Val','name','panel','uniprot','gene_name','gene_description','P.Value')] # keep only desired columns



#Show dfs of significant hits (there are none)
sig_const <- p_const[which(p_const$adj.P.Val < 0.05),]
sig_low <- p_low[which(p_low$adj.P.Val < 0.05),]
sig_diarrhea <- p_diarrhea[which(p_diarrhea$adj.P.Val < 0.05),]
rbind(sig_const,sig_low,sig_diarrhea)
p_df <- re_const

# Significant Genera Plot (plot 0)
plot0c <- ggplot(p_df, mapping = aes(x=logFC,y = -log10(P.Value), color = ifelse(adj.P.Val < 0.05,gene_name,"- Adj FDR P > 0.05")))+
  geom_point(size=0.1) +
  #geom_text(size=2.5, aes(label = ifelse(Severe.P.Val < 0.05,Combined,""), color = ifelse(Severe.P.Val < 0.05,Combined,"")),hjust = -0.05, vjust = 1, angle = 30, position = position_jitter(seed = 1))+
  geom_jitter(position = position_jitter(seed = 1)) +
 #ggtitle("Significant Genera") +
  xlab(bquote(beta~" Coefficient")) + 
  ylab(bquote("-log"[10]~"(P value)")) + 
  geom_vline(xintercept = 0)+
  #scale_x_break(c(-0.6, -18)) +
  scale_x_continuous(name = bquote(atop(beta["BMF"]~" Coefficient",italic("Constipation"))), 
                     guide = guide_axis(n.dodge = 2)) +
  theme(text = 
          element_text(size = 14), 
        plot.title = element_text(vjust = 0.5), 
        #plot.subtitle = element_text(size=8, hjust = 0.5), 
        legend.title = element_blank(), 
        axis.title.y = element_text(size = 8),
        axis.title.x = element_text(size = 8),
              legend.text  = element_text(size = 6.5),
              legend.position = "top",
              legend.box.just = "top",
              legend.key.size = unit(0.01, "cm"),
              legend.box.margin = margin(0, 1, 0, 1))+
          guides(shape = guide_legend(override.aes = list(size = 1)),
               color = guide_legend(override.aes = list(size = 1), nrow = 30),
               fill=guide_legend(title=NULL))
plot0c


p_df <- re_low

# Significant Genera Plot (plot 0)
plot0l <- ggplot(p_df, mapping = aes(x=logFC,y = -log10(P.Value), color = ifelse(adj.P.Val < 0.05,gene_name,"- Adj FDR P > 0.05")))+
  geom_point(size=0.1) +
  #geom_text(size=2.5, aes(label = ifelse(Severe.P.Val < 0.05,Combined,""), color = ifelse(Severe.P.Val < 0.05,Combined,"")),hjust = -0.05, vjust = 1, angle = 30, position = position_jitter(seed = 1))+
  geom_jitter(position = position_jitter(seed = 1)) +
 #ggtitle("Significant Genera") +
  xlab(bquote(beta~" Coefficient")) + 
  ylab(bquote("-log"[10]~"(P value)")) + 
  geom_vline(xintercept = 0)+
  #scale_x_break(c(-0.6, -18)) +
  scale_x_continuous(name = bquote(atop(beta["BMF"]~" Coefficient",italic("Low Normal"))), 
                     guide = guide_axis(n.dodge = 2)) +
  theme(text = 
          element_text(size = 14), 
        plot.title = element_text(vjust = 0.5), 
        #plot.subtitle = element_text(size=8, hjust = 0.5), 
        legend.title = element_blank(), 
        axis.title.y = element_text(size = 8),
        axis.title.x = element_text(size = 8),
              legend.text  = element_text(size = 6.5),
              legend.position = "top",
              legend.box.just = "top",
              legend.box.margin = margin(0, 1, 0, 1),
              legend.key.size = unit(0.01,"cm"))+
          guides(shape = guide_legend(override.aes = list(size = 1)),
               color = guide_legend(override.aes = list(size = 1), nrow = 30),
               fill=guide_legend(title=NULL))
plot0l


p_df <- re_diarrhea

# Significant Genera Plot (plot 0)
plot0d <- ggplot(p_df, mapping = aes(x=logFC,y = -log10(P.Value), color = ifelse(adj.P.Val < 0.05,gene_name,"- Adj FDR P > 0.05")))+
  geom_point(size=0.1) +
  #geom_text(size=2.5, aes(label = ifelse(Severe.P.Val < 0.05,Combined,""), color = ifelse(Severe.P.Val < 0.05,Combined,"")),hjust = -0.05, vjust = 1, angle = 30, position = position_jitter(seed = 1))+
  geom_jitter(position = position_jitter(seed = 1)) +
 #ggtitle("Significant Genera") +
  xlab(bquote(beta~" Coefficient")) + 
  ylab(bquote("-log"[10]~"(P value)")) + 
  geom_vline(xintercept = 0)+
  #scale_x_break(c(-0.6, -18)) +
  scale_x_continuous(name = bquote(atop(beta["BMF"]~" Coefficient",italic("Diarrhea"))), 
                     guide = guide_axis(n.dodge = 2)) +
  theme(text = 
          element_text(size = 14), 
        plot.title = element_text(vjust = 0.5), 
        #plot.subtitle = element_text(size=8, hjust = 0.5), 
        legend.title = element_blank(), 
        axis.title.y = element_text(size = 8),
        axis.title.x = element_text(size = 8),
              legend.text  = element_text(size = 6.5),
              legend.position = "top",
              legend.box.just = "top",
              legend.box.margin = margin(0, 1, 0, 1),
              legend.key.size = unit(0.01, "cm"))+
          guides(shape = guide_legend(override.aes = list(size = 1)),
               color = guide_legend(override.aes = list(size = 1), nrow = 30),
               fill=guide_legend(title=NULL))
plot0d

library(ggpubr)
figure <- ggarrange(plot0c,plot0l,plot0d, common.legend = FALSE, nrows = 1, ncols = 3, align = "hv", legend = "bottom", widths = c(1,1,1), heights = c(50,50,50)) + theme(plot.margin = unit(c(0,5,0,5), "cm"),        #plot.subtitle = element_text(size=8, hjust = 0.5), 
        legend.title = element_blank(), 
        axis.title.y = element_text(size = 8),
        axis.title.x = element_text(size = 8),
              legend.text  = element_text(size = 8),
              legend.position = "bottom",
              legend.box.just = "bottom",
              legend.box.margin = margin(0, 1, 0, 1),
              legend.key.size = unit(0.01,"cm"))+
          guides(shape = guide_legend(override.aes = list(size = 1)),
               color = guide_legend(override.aes = list(size = 1), nrow = 20),
               fill=guide_legend(title=NULL))

ggsave(
  "BMFvsProteinsVolcano.png",
  plot = figure,
  device = NULL,
  path = NULL,
  scale = 2.5,
  width = NA,
  height = NA,
  units = c("in", "cm", "mm", "px"),
  dpi = 300,
  limitsize = TRUE,
  bg = NULL
)
Saving 18.2 x 11.3 in image

figure

#Plotting
library(tidyverse)
library(dplyr)
library(ggpubr)
library(stringr)
library(ggprism)
library(patchwork)
library(magrittr)
library(ggbeeswarm)
library(data.table)
comparisons = list(c("Low Normal","High Normal"),c("Diarrhea","High Normal"))

sig_low['bowel'] <- rep('Low Normal',1)
sig_diarrhea['bowel']  <- rep('Diarrhea',25)
bound <- rbind(sig_low,sig_diarrhea)
a <- full[,names(full) %in% bound['name'][[1]]]
setcolorder(a,bound['name'][[1]])
names(a) <- bound['gene_name'][[1]]
biochemistry <- cbind(full[,1:6],a)
names(biochemistry)[11] <- 'TNFRSF11B (2nd Instance)'
biochemistry$bowel <- factor(biochemistry$bowel, levels=c(1,2,3,4), labels = c("Constipation","Low Normal","High Normal","Diarrhea"))
biochemistry$bowel <- factor(biochemistry$bowel, levels=c("Constipation","Low Normal","High Normal","Diarrhea"), labels = c("Constipation","Low Normal","High Normal","Diarrhea"))


sig = function(x){
  if(x < 0.001){"***"} 
  else if(x < 0.01){"**"}
  else if(x < 0.05){"*"}
  else{NA}}

test = function(x,y,z,j) {
  x = NULL
  y = NULL
  if (counter == 1) {
    z = comparisons[[1]][1]
  } else {
    z = comparisons[[2]][1]
    counter<<-0
  }
  print(j)
  if (str_detect(z,"Diarrhea") & any(sig_diarrhea[,'gene_name']==j)) {
    results = list(p.value = sig_diarrhea[which(sig_diarrhea[,'gene_name']==j),]['adj.P.Val'][[1]])
  } else if (str_detect(z,"Low Normal") & any(sig_low[,'gene_name']==j)) {
    results = list(p.value = sig_low[which(sig_low[,'gene_name']==j),]['adj.P.Val'][[1]])
  } else {
    results = list(p.value = 1)
  }
  names(results) <- 'p.value'
  counter <<-counter+1
  return(results)
}

counter <<-1
myplots <- list()  # new empty list
  for (ind in 1:(ncol(biochemistry)-6)) {
  myplots[[ind]] <- local({
    label = paste(names(biochemistry)[ind+6],sep="")
    sub = ifelse(label!='TNFRSF11B (2nd Instance)',paste(bound['gene_description'][which(bound['gene_name']==label),]),paste(bound['gene_description'][which(bound['gene_name']=='TNFRSF11B'),]))
    print(label)
    print(sub)
    n = 2
    plotlim_lower = min(biochemistry[!is.na(biochemistry[,ind+6]),][,ind+6])
    plotlim_upper = max(biochemistry[!is.na(biochemistry[,ind+6]),][,ind+6])
    plotlim_bar = plotlim_lower - n
    plotlim_margin = abs(plotlim_bar - n*10)
    sublabel <- 'TNFRSF11B'
    plt <- ggplot(data = biochemistry, aes(x = bowel, y = .data[[label]], group = bowel)) +
    scale_x_discrete(guide = guide_axis(n.dodge = 2))+
    geom_beeswarm(aes(color = bowel), size = 0.1, cex = 0.5) +
    geom_boxplot(alpha=0.0,outlier.shape = NA) +
    theme(text = element_text(size = 9)) +
    ggtitle(label = str_wrap(label, width = 2),subtitle=str_wrap(sub,width=20)) +
    coord_cartesian(ylim=c(plotlim_lower,plotlim_upper),clip="off")+
    geom_signif(comparisons = comparisons, map_signif_level = sig, test = 'test', test.args = list(z = comparisons, j = ifelse(label!='TNFRSF11B (2nd Instance)',label,sublabel)), 
                y_position = plotlim_bar, 
                step_increase = 0.10,  size = 0.5, 
                textsize = 1.5,
                tip_length = c(0,0)) +
    labs(color = "BMF Category", y = ifelse((ind == 1 | ind == 6 | ind == 11 | ind == 16 | ind == 21 | ind == 26),"Protein Level",""))+
    guides(colour = guide_legend(override.aes = list(size=7), title.position = 'left', nrow = 1, ncol = 4)) +
    theme(plot.margin = unit(c(0,0,plotlim_margin,0), "pt"),  
          plot.title = element_text(size=5.75), 
          plot.subtitle = element_text(size=4.5), 
          legend.title = element_text(size=10),
          legend.text = element_text(size=7),
          axis.text.x = element_blank(), 
          axis.text.y = element_text(size=7), 
          axis.title.y = element_text(size=7),
          axis.title.x = element_blank(),
          aspect.ratio = 0.95)+
    scale_fill_manual(limits = c("Constipation","Low Normal","High Normal","Diarrhea"), labels = c("Constipation","Low Normal","High Normal","Diarrhea"), values = colors(),
                    drop = FALSE)
  print(plt)
  })
}
[1] "HAVCR1"
[1] "hepatitis A virus cellular receptor 1"
[1] "HAVCR1"
[1] "HAVCR1"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "TNFRSF11B"
[1] "tumor necrosis factor receptor superfamily, member 11b"
[1] "TNFRSF11B"
[1] "TNFRSF11B"
Warning in if (x < 0.001) { :
  the condition has length > 1 and only the first element will be used
Warning in if (x < 0.01) { :
  the condition has length > 1 and only the first element will be used
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "HGF"
[1] "hepatocyte growth factor (hepapoietin A; scatter factor)"
[1] "HGF"
[1] "HGF"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "TEK"
[1] "TEK tyrosine kinase, endothelial"
[1] "TEK"
[1] "TEK"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "TNFRSF11B (2nd Instance)"
[1] "tumor necrosis factor receptor superfamily, member 11b"
[1] "TNFRSF11B"
[1] "TNFRSF11B"
Warning in if (x < 0.001) { :
  the condition has length > 1 and only the first element will be used
Warning in if (x < 0.01) { :
  the condition has length > 1 and only the first element will be used
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "TGFA"
[1] "transforming growth factor, alpha"
[1] "TGFA"
[1] "TGFA"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "CSF1"
[1] "colony stimulating factor 1 (macrophage)"
[1] "CSF1"
[1] "CSF1"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "VEGFA"
[1] "vascular endothelial growth factor A"
[1] "VEGFA"
[1] "VEGFA"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "LIFR"
[1] "leukemia inhibitory factor receptor alpha"
[1] "LIFR"
[1] "LIFR"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "TNFRSF9"
[1] "tumor necrosis factor receptor superfamily, member 9"
[1] "TNFRSF9"
[1] "TNFRSF9"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "IL10RB"
[1] "interleukin 10 receptor, beta"
[1] "IL10RB"
[1] "IL10RB"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "FST"
[1] "follistatin"
[1] "FST"
[1] "FST"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "GDF15"
[1] "growth differentiation factor 15"
[1] "GDF15"
[1] "GDF15"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "RARRES2"
[1] "retinoic acid receptor responder (tazarotene induced) 2"
[1] "RARRES2"
[1] "RARRES2"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "IL1RN"
[1] "interleukin 1 receptor antagonist"
[1] "IL1RN"
[1] "IL1RN"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "LDLR"
[1] "low density lipoprotein receptor"
[1] "LDLR"
[1] "LDLR"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "CTSD"
[1] "cathepsin D"
[1] "CTSD"
[1] "CTSD"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "ICAM2"
[1] "intercellular adhesion molecule 2"
[1] "ICAM2"
[1] "ICAM2"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "ADA"
[1] "adenosine deaminase"
[1] "ADA"
[1] "ADA"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "PLAUR"
[1] "plasminogen activator, urokinase receptor"
[1] "PLAUR"
[1] "PLAUR"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "TREML2"
[1] "triggering receptor expressed on myeloid cells-like 2"
[1] "TREML2"
[1] "TREML2"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "CTSZ"
[1] "cathepsin Z"
[1] "CTSZ"
[1] "CTSZ"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "CCL4"
[1] "chemokine (C-C motif) ligand 4"
[1] "CCL4"
[1] "CCL4"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "DNER"
[1] "delta/notch-like EGF repeat containing"
[1] "DNER"
[1] "DNER"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "CCL13"
[1] "chemokine (C-C motif) ligand 13"
[1] "CCL13"
[1] "CCL13"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "CDCP1"
[1] "CUB domain containing protein 1"
[1] "CDCP1"
[1] "CDCP1"
Warning: Removed 3 rows containing missing values (geom_signif).

library(r2symbols)
counter<<- 1
figure1 <- ggarrange(plotlist = myplots[1:10], labels = c(LETTERS[1:10]), legend = "top", align = "hv", font.label = list(size = 9.5), common.legend = TRUE, nrow = 2, ncol = 5, legend.grob = get_legend(myplots[[2]]))
[1] "TNFRSF11B"
[1] "TNFRSF11B"
Warning in if (x < 0.001) { :
  the condition has length > 1 and only the first element will be used
Warning in if (x < 0.01) { :
  the condition has length > 1 and only the first element will be used
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "HAVCR1"
[1] "HAVCR1"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "TNFRSF11B"
[1] "TNFRSF11B"
Warning in if (x < 0.001) { :
  the condition has length > 1 and only the first element will be used
Warning in if (x < 0.01) { :
  the condition has length > 1 and only the first element will be used
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "HGF"
[1] "HGF"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "TEK"
[1] "TEK"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "TNFRSF11B"
[1] "TNFRSF11B"
Warning in if (x < 0.001) { :
  the condition has length > 1 and only the first element will be used
Warning in if (x < 0.01) { :
  the condition has length > 1 and only the first element will be used
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "TGFA"
[1] "TGFA"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "CSF1"
[1] "CSF1"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "VEGFA"
[1] "VEGFA"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "LIFR"
[1] "LIFR"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "TNFRSF9"
[1] "TNFRSF9"
Warning: Removed 3 rows containing missing values (geom_signif).
                                                                                                             
figure1


counter <<- 1
figure2 <- ggarrange(plotlist = myplots[11:20], labels = c(LETTERS[11:20]), font.label = list(size = 9.5), legend = "none", align = "hv", nrow = 2, ncol = 5)
[1] "IL10RB"
[1] "IL10RB"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "FST"
[1] "FST"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "GDF15"
[1] "GDF15"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "RARRES2"
[1] "RARRES2"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "IL1RN"
[1] "IL1RN"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "LDLR"
[1] "LDLR"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "CTSD"
[1] "CTSD"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "ICAM2"
[1] "ICAM2"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "ADA"
[1] "ADA"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "PLAUR"
[1] "PLAUR"
Warning: Removed 3 rows containing missing values (geom_signif).
figure2



counter <<- 1
figure3 <- ggarrange(plotlist = myplots[21:26], labels = c(LETTERS[21:26]), font.label = list(size = 9.5), legend = "none", align = "hv", nrow = 2, ncol = 5)
[1] "TREML2"
[1] "TREML2"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "CTSZ"
[1] "CTSZ"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "CCL4"
[1] "CCL4"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "DNER"
[1] "DNER"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "CCL13"
[1] "CCL13"
Warning: Removed 3 rows containing missing values (geom_signif).
[1] "CDCP1"
[1] "CDCP1"
Warning: Removed 3 rows containing missing values (geom_signif).
figure3

#Main Text Figures
counter <<- 1
figure_main1 <- ggarrange(plotlist = list(figure1,figure2,figure3), legend = "top", align = "hv", common.legend = TRUE, nrow = 3, ncol = 1)
figure_main1

counter <<- 1
ggsave(
  "BMFvsProteins1.png",
  plot = figure1,
  device = NULL,
  path = NULL,
  scale = 1.5,
  width = NA,
  height = NA,
  units = c("in", "cm", "mm", "px"),
  dpi = 300,
  limitsize = TRUE,
  bg = NULL
)
Saving 7 x 7 in image
counter <<- 1
ggsave(
  "BMFvsProteins2.png",
  plot = figure2,
  device = NULL,
  path = NULL,
  scale = 1.5,
  width = NA,
  height = NA,
  units = c("in", "cm", "mm", "px"),
  dpi = 300,
  limitsize = TRUE,
  bg = NULL
)
Saving 7 x 7 in image
counter <<- 1
ggsave(
  "BMFvsProteins3.png",
  plot = figure3,
  device = NULL,
  path = NULL,
  scale = 1.5,
  width = NA,
  height = NA,
  units = c("in", "cm", "mm", "px"),
  dpi = 300,
  limitsize = TRUE,
  bg = NULL
)
Saving 7 x 7 in image
counter <<- 1
ggsave(
  "BMFvsProteinsMain.png",
  plot = figure_main1,
  device = NULL,
  path = NULL,
  scale = 100,
  width = NA,
  height = NA,
  units = c("in", "cm", "mm", "px"),
  dpi = 300,
  limitsize = TRUE,
  bg = NULL
)
Saving 7 x 7 in image

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

LS0tCnRpdGxlOiAiUHJvdGVvbWljcyBMSU1NQSBSZWdyZXNzaW9uIC0gSmFtZXMgSm9obnNvbiAtIHYxLTE4LTIyIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiAKClRyeSBleGVjdXRpbmcgdGhpcyBjaHVuayBieSBjbGlja2luZyB0aGUgKlJ1biogYnV0dG9uIHdpdGhpbiB0aGUgY2h1bmsgb3IgYnkgcGxhY2luZyB5b3VyIGN1cnNvciBpbnNpZGUgaXQgYW5kIHByZXNzaW5nICpDdHJsK1NoaWZ0K0VudGVyKi4gCgpgYGB7cn0KI0xvYWQgc29tZSB1c2VmdWwgbGlicmFyaWVzCmxpYnJhcnkobGltbWEpCmxpYnJhcnkoREVTZXEyKQpsaWJyYXJ5KGVkZ2VSKQpsaWJyYXJ5KGRhdGEudGFibGUpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkobWFncml0dHIpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHNqbGFiZWxsZWQpCmxpYnJhcnkoc2ptaXNjKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkoRGF0YUNvbWJpbmUpCmBgYAoKCmBgYHtyfQojaW1wb3J0IGRhdGEKY291bnRkZiA8LSBEcm9wTkEocmVhZC5jc3YoZmlsZSA9ICdwcm90ZW9taWNzLmNzdicpKQpyb3duYW1lcyhjb3VudGRmKSA8LSBOVUxMCm1ldGEgPC0gRHJvcE5BKHJlYWQuY3N2KGZpbGUgPSAncHJvdGVvbWljc19tZXRhZGF0YS5jc3YnKSkKcm93bmFtZXMobWV0YSkgPC0gTlVMTAphbm5vIDwtIERyb3BOQShyZWFkLmNzdihmaWxlID0gJ3Byb3Rlb21pY3NfbWV0YWRhdGFfdGFibGUuY3N2JykpCnJvd25hbWVzKGFubm8pIDwtIE5VTEwKZnVsbCA8LSBEcm9wTkEocmVhZC5jc3YoZmlsZSA9ICdwcm90ZW9taWNzX2Z1bGwuY3N2JykpCnJvd25hbWVzKGZ1bGwpIDwtIE5VTEwKCiNjbGVhbi11cCB0YWJsZXMKI3ByZXBhcmUgZm9yIG1vZGVsCiNtYWtlIGNvbnNpc3RlbnQgaW5kZXgvY29sdW1uL2xhYmVsL29yZGVyaW5nIGJldHdlZW4gdGFibGVzL21hdHJpY2VzCm5hbWVzKGNvdW50ZGYpWzFdIDwtICduYW1lJwojY291bnRkZltjb3VudGRmPT0wXSA8LSAwLjAwMDAwMDEKI2NvdW50ZGZbY291bnRkZjwwXSA8LSAwLjAwMDAwMDEKbmFtZXMoY291bnRkZikgPC0gc2FwcGx5KHN0cl9yZW1vdmVfYWxsKG5hbWVzKGNvdW50ZGYpLCJYIiksIlsiKSAjIHJlbW92ZSBhZGRlZCBYJ3MgZnJvbSBQQ0kgbmFtZXMKY291bnRfbWF0cml4IDwtIGNvdW50ZGZbLDI6bmNvbChjb3VudGRmKV0KY291bnRfbWF0cml4IDwtIGFzLm1hdHJpeChjb3VudF9tYXRyaXgpCiNjb3VudF9tYXRyaXhbLDFdIDwtIE5VTEwKbmFtZXMoZnVsbCkgPC0gc2FwcGx5KHN0cl9yZW1vdmVfYWxsKGNvbG5hbWVzKGZ1bGwpLCJYIiksIlsiKQpuYW1lcyhjb3VudF9tYXRyaXgpIDwtIHNhcHBseShzdHJfcmVtb3ZlX2FsbChjb2xuYW1lcyhjb3VudF9tYXRyaXgpLCJYIiksIlsiKQptZXRhJHNleCA8LSBmYWN0b3IobWV0YSRzZXgpCmZ1bGwkc2V4IDwtIGZhY3RvcihmdWxsJHNleCkKbWV0YSRib3dlbCA8LSBmYWN0b3IoYXMubnVtZXJpYyhmYWN0b3IobWV0YSRib3dlbCwgbGV2ZWxzID0gYygxLDIsMyw0KSwgbGFiZWxzID0gYygxLDIsMyw0KSkpKQpmdWxsJGJvd2VsIDwtIGZhY3Rvcihhcy5udW1lcmljKGZhY3RvcihmdWxsJGJvd2VsLCBsZXZlbHMgPSBjKDEsMiwzLDQpLCBsYWJlbHMgPSBjKDEsMiwzLDQpKSkpCm1ldGEgPC0gd2l0aGluKG1ldGEsIGJvd2VsIDwtIHJlbGV2ZWwoYm93ZWwsIHJlZiA9IDMpKQpmdWxsIDwtIHdpdGhpbihmdWxsLCBib3dlbCA8LSByZWxldmVsKGJvd2VsLCByZWYgPSAzKSkKY291bnRfbWF0cml4CmNvdW50ZGYKbWV0YQphbm5vCmZ1bGwKYGBgCgoKCmBgYHtyfQojIERlc2lnbiBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbHMgdXNpbmcgbG1GaXQgYW5kIGVCYXllcyB3aXRoIExJTU1BCiMgVGhpcyBjb2RlIGFkYXB0ZWQgZnJvbSBDaHJpc3RpYW4gRGllbmVyLCBQaEQ6CmRlc2lnbiA8LSBtb2RlbC5tYXRyaXgofmJvd2VsICsgc2V4ICsgYWdlICsgQk1JX0NBTEMgKyBlR0ZSLCBtZXRhKSAjIENvdmFyaWF0ZXM6IHNleCwgYWdlLCBCTUkKI2RnZSA8LSBER0VMaXN0KGNvdW50cz1jb3VudF9tYXRyaXgpICAjIFdoZXJlIGBjb3VudF9tYXRyaXhgIGlzIHRoZSBtYXRyaXggbWVudGlvbmVkIGFib3ZlCiNkZ2UgPC0gY2FsY05vcm1GYWN0b3JzKGNvdW50X21hdHJpeCkgICMgTm9ybWFsaXplIHRoZSBtYXRyaXggKHRoaXMgc3RlcCBvbmx5IGZvciBDT1JOQ09CL21pY3JvYmlvbWUgZGF0YSkKI2xvZ0NQTSA8LSBjcG0oZGdlLCBsb2c9RkFMU0UpICAjIFRha2VzIHRoZSBsb2cgb2YgdGhlIGRhdGEKZml0IDwtIGxtRml0KGNvdW50X21hdHJpeCwgZGVzaWduKSAgIyBGaXRzIHRoZSBtb2RlbCBmb3IgYWxsIG1ldGFib2xpdGVzCmZpdCA8LSBlQmF5ZXMoZml0KSAgIyBTdGFiaWxpemVzIHRoZSB2YXJpYW5jZXMKZml0CmBgYAoKCmBgYHtyfQojUHJlLXByb2Nlc3MgZm9yIHBsb3R0aW5nOgojR2V0IHJlc3VsdHMgdGFibGUgZm9yIENvbnN0aXBhdGlvbiBjb2VmZmljaWVudCByZWxhdGl2ZSB0byBIaWdoIE5vcm1hbCBCTUY6CnJlX2NvbnN0IDwtIHRvcFRhYmxlKGZpdCwgY29lZiA9IDIsIGdlbmVsaXN0ID0gYW5ubywgc29ydD0icCIsIG51bWJlcj0ibm9uZSIpICAjIFNlbGVjdCB0aGUgc2lnbmlmaWNhbnQgbW9kZWxzIGJ5IGNvZWZmaWNpZW50IDIKCmluZGljZXMgPC0gbWF0Y2gocm93bmFtZXMocmVfY29uc3QpLCByb3duYW1lcyhhbm5vKSkgIyBhc3NvY2lhdGUgY29sdW1uIG9mIHByb3RlaW4gbmFtZXMgd2l0aCBpbmRleCBvZiBwcm90ZWluCnJlX2NvbnN0WzFdIDwtIGFubm8kbmFtZVtpbmRpY2VzXSAjIGFzc29jaWF0ZSB0aGUgcHJvdGVpbiBuYW1lcyB3aXRoIHRoZSBwcm90ZWluIGluZGljZXMKcmVfY29uc3QgPC0gZHBseXI6OmlubmVyX2pvaW4oYW5ubywgcmVfY29uc3QsIGJ5ID0gaW50ZXJzZWN0KG5hbWVzKGFubm8pLG5hbWVzKHJlX2NvbnN0KSkpICNjb21iaW5lIGFubm8gYW5kIHJlIGRmcyBieSBpbnRlcnNlY3Rpb24gb2YgcHJvdGVpbiB2YWx1ZXMKcF9jb25zdCA8LSByZV9jb25zdFtyZV9jb25zdCRhZGouUC5WYWwgPCAwLjA1LF0gIyBjcmVhdGUgZGYgb2YganVzdCBzaWduaWZpY2FudCBhZGogUCB2YWx1ZSByZXN1bHRzCnBfY29uc3QgPC0gcF9jb25zdFtvcmRlcihwX2NvbnN0JGFkai5QLlZhbCksXSAjIG9yZGVyIGJ5IGFkaiBQIHZhbHVlCnBfY29uc3QgPC0gcF9jb25zdFssYygnbG9nRkMnLCdCJywnYWRqLlAuVmFsJywnbmFtZScsJ3BhbmVsJywndW5pcHJvdCcsJ2dlbmVfbmFtZScsJ2dlbmVfZGVzY3JpcHRpb24nLCdQLlZhbHVlJyldICMga2VlcCBvbmx5IGRlc2lyZWQgY29sdW1ucwoKI1ByZS1wcm9jZXNzIGZvciBwbG90dGluZzoKI0dldCByZXN1bHRzIHRhYmxlIGZvciBMb3cgTm9ybWFsIGNvZWZmaWNpZW50IHJlbGF0aXZlIHRvIEhpZ2ggTm9ybWFsIEJNRjoKcmVfbG93IDwtIHRvcFRhYmxlKGZpdCwgY29lZiA9IDMsIGdlbmVsaXN0ID0gYW5ubywgc29ydD0icCIsIG51bWJlcj0ibm9uZSIpICAjIFNlbGVjdCB0aGUgc2lnbmlmaWNhbnQgbW9kZWxzIGJ5IGNvZWZmaWNpZW50IDMKCmluZGljZXMgPC0gbWF0Y2gocm93bmFtZXMocmVfbG93KSwgcm93bmFtZXMoYW5ubykpICMgYXNzb2NpYXRlIGNvbHVtbiBvZiBwcm90ZWluIG5hbWVzIHdpdGggaW5kZXggb2YgcHJvdGVpbgpyZV9sb3dbMV0gPC0gYW5ubyRuYW1lW2luZGljZXNdICMgYXNzb2NpYXRlIHRoZSBwcm90ZWluIG5hbWVzIHdpdGggdGhlIHByb3RlaW4gaW5kaWNlcwpyZV9sb3cgPC0gZHBseXI6OmlubmVyX2pvaW4oYW5ubywgcmVfbG93LCBieSA9IGludGVyc2VjdChuYW1lcyhhbm5vKSxuYW1lcyhyZV9sb3cpKSkgI2NvbWJpbmUgYW5ubyBhbmQgcmUgZGZzIGJ5IGludGVyc2VjdGlvbiBvZiBwcm90ZWluIHZhbHVlcwpwX2xvdyA8LSByZV9sb3dbcmVfbG93JGFkai5QLlZhbCA8IDAuMDUsXSAjIGNyZWF0ZSBkZiBvZiBqdXN0IHNpZ25pZmljYW50IGFkaiBQIHZhbHVlIHJlc3VsdHMKcF9sb3cgPC0gcF9sb3dbb3JkZXIocF9sb3ckYWRqLlAuVmFsKSxdICMgb3JkZXIgYnkgYWRqIFAgdmFsdWUKcF9sb3cgPC0gcF9sb3dbLGMoJ2xvZ0ZDJywnQicsJ2Fkai5QLlZhbCcsJ25hbWUnLCdwYW5lbCcsJ3VuaXByb3QnLCdnZW5lX25hbWUnLCdnZW5lX2Rlc2NyaXB0aW9uJywnUC5WYWx1ZScpXSAjIGtlZXAgb25seSBkZXNpcmVkIGNvbHVtbnMKCiNQcmUtcHJvY2VzcyBmb3IgcGxvdHRpbmc6CiNHZXQgcmVzdWx0cyB0YWJsZSBmb3IgRGlhcnJoZWEgY29lZmZpY2llbnQgcmVsYXRpdmUgdG8gSGlnaCBOb3JtYWwgQk1GOgpyZV9kaWFycmhlYSA8LSB0b3BUYWJsZShmaXQsIGNvZWYgPSA0LCBnZW5lbGlzdCA9IGFubm8sIHNvcnQ9InAiLCBudW1iZXI9Im5vbmUiKSAgIyBTZWxlY3QgdGhlIHNpZ25pZmljYW50IG1vZGVscyBieSBjb2VmZmljaWVudCA0CgppbmRpY2VzIDwtIG1hdGNoKHJvd25hbWVzKHJlX2RpYXJyaGVhKSwgcm93bmFtZXMoYW5ubykpICMgYXNzb2NpYXRlIGNvbHVtbiBvZiBwcm90ZWluIG5hbWVzIHdpdGggaW5kZXggb2YgcHJvdGVpbgpyZV9kaWFycmhlYVsxXSA8LSBhbm5vJG5hbWVbaW5kaWNlc10gIyBhc3NvY2lhdGUgdGhlIHByb3RlaW4gbmFtZXMgd2l0aCB0aGUgcHJvdGVpbiBpbmRpY2VzCnJlX2RpYXJyaGVhIDwtIGRwbHlyOjppbm5lcl9qb2luKGFubm8sIHJlX2RpYXJyaGVhLCBieSA9IGludGVyc2VjdChuYW1lcyhhbm5vKSxuYW1lcyhyZV9kaWFycmhlYSkpKSAjY29tYmluZSBhbm5vIGFuZCByZSBkZnMgYnkgaW50ZXJzZWN0aW9uIG9mIHByb3RlaW4gdmFsdWVzCnBfZGlhcnJoZWEgPC0gcmVfZGlhcnJoZWFbcmVfZGlhcnJoZWEkYWRqLlAuVmFsIDwgMC4wNSxdICMgY3JlYXRlIGRmIG9mIGp1c3Qgc2lnbmlmaWNhbnQgYWRqIFAgdmFsdWUgcmVzdWx0cwpwX2RpYXJyaGVhIDwtIHBfZGlhcnJoZWFbb3JkZXIocF9kaWFycmhlYSRhZGouUC5WYWwpLF0gIyBvcmRlciBieSBhZGogUCB2YWx1ZQpwX2RpYXJyaGVhIDwtIHBfZGlhcnJoZWFbLGMoJ2xvZ0ZDJywnQicsJ2Fkai5QLlZhbCcsJ25hbWUnLCdwYW5lbCcsJ3VuaXByb3QnLCdnZW5lX25hbWUnLCdnZW5lX2Rlc2NyaXB0aW9uJywnUC5WYWx1ZScpXSAjIGtlZXAgb25seSBkZXNpcmVkIGNvbHVtbnMKCgoKI1Nob3cgZGZzIG9mIHNpZ25pZmljYW50IGhpdHMgKHRoZXJlIGFyZSBub25lKQpzaWdfY29uc3QgPC0gcF9jb25zdFt3aGljaChwX2NvbnN0JGFkai5QLlZhbCA8IDAuMDUpLF0Kc2lnX2xvdyA8LSBwX2xvd1t3aGljaChwX2xvdyRhZGouUC5WYWwgPCAwLjA1KSxdCnNpZ19kaWFycmhlYSA8LSBwX2RpYXJyaGVhW3doaWNoKHBfZGlhcnJoZWEkYWRqLlAuVmFsIDwgMC4wNSksXQpyYmluZChzaWdfY29uc3Qsc2lnX2xvdyxzaWdfZGlhcnJoZWEpCmBgYAoKCmBgYHtyfQpwX2RmIDwtIHJlX2NvbnN0CgojIFNpZ25pZmljYW50IEdlbmVyYSBQbG90IChwbG90IDApCnBsb3QwYyA8LSBnZ3Bsb3QocF9kZiwgbWFwcGluZyA9IGFlcyh4PWxvZ0ZDLHkgPSAtbG9nMTAoUC5WYWx1ZSksIGNvbG9yID0gaWZlbHNlKGFkai5QLlZhbCA8IDAuMDUsZ2VuZV9uYW1lLCItIEFkaiBGRFIgUCA+IDAuMDUiKSkpKwogIGdlb21fcG9pbnQoc2l6ZT0wLjEpICsKICAjZ2VvbV90ZXh0KHNpemU9Mi41LCBhZXMobGFiZWwgPSBpZmVsc2UoU2V2ZXJlLlAuVmFsIDwgMC4wNSxDb21iaW5lZCwiIiksIGNvbG9yID0gaWZlbHNlKFNldmVyZS5QLlZhbCA8IDAuMDUsQ29tYmluZWQsIiIpKSxoanVzdCA9IC0wLjA1LCB2anVzdCA9IDEsIGFuZ2xlID0gMzAsIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHNlZWQgPSAxKSkrCiAgZ2VvbV9qaXR0ZXIocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIoc2VlZCA9IDEpKSArCiAjZ2d0aXRsZSgiU2lnbmlmaWNhbnQgR2VuZXJhIikgKwogIHhsYWIoYnF1b3RlKGJldGF+IiBDb2VmZmljaWVudCIpKSArIAogIHlsYWIoYnF1b3RlKCItbG9nIlsxMF1+IihQIHZhbHVlKSIpKSArIAogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDApKwogICNzY2FsZV94X2JyZWFrKGMoLTAuNiwgLTE4KSkgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gYnF1b3RlKGF0b3AoYmV0YVsiQk1GIl1+IiBDb2VmZmljaWVudCIsaXRhbGljKCJDb25zdGlwYXRpb24iKSkpLCAKICAgICAgICAgICAgICAgICAgICAgZ3VpZGUgPSBndWlkZV9heGlzKG4uZG9kZ2UgPSAyKSkgKwogIHRoZW1lKHRleHQgPSAKICAgICAgICAgIGVsZW1lbnRfdGV4dChzaXplID0gMTQpLCAKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMC41KSwgCiAgICAgICAgI3Bsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04LCBoanVzdCA9IDAuNSksIAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgICAgICAgICAgIGxlZ2VuZC50ZXh0ICA9IGVsZW1lbnRfdGV4dChzaXplID0gNi41KSwKICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgICAgICAgICAgICBsZWdlbmQuYm94Lmp1c3QgPSAidG9wIiwKICAgICAgICAgICAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuMDEsICJjbSIpLAogICAgICAgICAgICAgIGxlZ2VuZC5ib3gubWFyZ2luID0gbWFyZ2luKDAsIDEsIDAsIDEpKSsKICAgICAgICAgIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAxKSksCiAgICAgICAgICAgICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDEpLCBucm93ID0gMzApLAogICAgICAgICAgICAgICBmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkKcGxvdDBjCgpwX2RmIDwtIHJlX2xvdwoKIyBTaWduaWZpY2FudCBHZW5lcmEgUGxvdCAocGxvdCAwKQpwbG90MGwgPC0gZ2dwbG90KHBfZGYsIG1hcHBpbmcgPSBhZXMoeD1sb2dGQyx5ID0gLWxvZzEwKFAuVmFsdWUpLCBjb2xvciA9IGlmZWxzZShhZGouUC5WYWwgPCAwLjA1LGdlbmVfbmFtZSwiLSBBZGogRkRSIFAgPiAwLjA1IikpKSsKICBnZW9tX3BvaW50KHNpemU9MC4xKSArCiAgI2dlb21fdGV4dChzaXplPTIuNSwgYWVzKGxhYmVsID0gaWZlbHNlKFNldmVyZS5QLlZhbCA8IDAuMDUsQ29tYmluZWQsIiIpLCBjb2xvciA9IGlmZWxzZShTZXZlcmUuUC5WYWwgPCAwLjA1LENvbWJpbmVkLCIiKSksaGp1c3QgPSAtMC4wNSwgdmp1c3QgPSAxLCBhbmdsZSA9IDMwLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihzZWVkID0gMSkpKwogIGdlb21faml0dGVyKHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHNlZWQgPSAxKSkgKwogI2dndGl0bGUoIlNpZ25pZmljYW50IEdlbmVyYSIpICsKICB4bGFiKGJxdW90ZShiZXRhfiIgQ29lZmZpY2llbnQiKSkgKyAKICB5bGFiKGJxdW90ZSgiLWxvZyJbMTBdfiIoUCB2YWx1ZSkiKSkgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSsKICAjc2NhbGVfeF9icmVhayhjKC0wLjYsIC0xOCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9IGJxdW90ZShhdG9wKGJldGFbIkJNRiJdfiIgQ29lZmZpY2llbnQiLGl0YWxpYygiTG93IE5vcm1hbCIpKSksIAogICAgICAgICAgICAgICAgICAgICBndWlkZSA9IGd1aWRlX2F4aXMobi5kb2RnZSA9IDIpKSArCiAgdGhlbWUodGV4dCA9IAogICAgICAgICAgZWxlbWVudF90ZXh0KHNpemUgPSAxNCksIAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQodmp1c3QgPSAwLjUpLCAKICAgICAgICAjcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgsIGhqdXN0ID0gMC41KSwgCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgID0gZWxlbWVudF90ZXh0KHNpemUgPSA2LjUpLAogICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgICAgICAgICAgIGxlZ2VuZC5ib3guanVzdCA9ICJ0b3AiLAogICAgICAgICAgICAgIGxlZ2VuZC5ib3gubWFyZ2luID0gbWFyZ2luKDAsIDEsIDAsIDEpLAogICAgICAgICAgICAgIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC4wMSwiY20iKSkrCiAgICAgICAgICBndWlkZXMoc2hhcGUgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gMSkpLAogICAgICAgICAgICAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAxKSwgbnJvdyA9IDMwKSwKICAgICAgICAgICAgICAgZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9TlVMTCkpCnBsb3QwbAoKcF9kZiA8LSByZV9kaWFycmhlYQoKIyBTaWduaWZpY2FudCBHZW5lcmEgUGxvdCAocGxvdCAwKQpwbG90MGQgPC0gZ2dwbG90KHBfZGYsIG1hcHBpbmcgPSBhZXMoeD1sb2dGQyx5ID0gLWxvZzEwKFAuVmFsdWUpLCBjb2xvciA9IGlmZWxzZShhZGouUC5WYWwgPCAwLjA1LGdlbmVfbmFtZSwiLSBBZGogRkRSIFAgPiAwLjA1IikpKSsKICBnZW9tX3BvaW50KHNpemU9MC4xKSArCiAgI2dlb21fdGV4dChzaXplPTIuNSwgYWVzKGxhYmVsID0gaWZlbHNlKFNldmVyZS5QLlZhbCA8IDAuMDUsQ29tYmluZWQsIiIpLCBjb2xvciA9IGlmZWxzZShTZXZlcmUuUC5WYWwgPCAwLjA1LENvbWJpbmVkLCIiKSksaGp1c3QgPSAtMC4wNSwgdmp1c3QgPSAxLCBhbmdsZSA9IDMwLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihzZWVkID0gMSkpKwogIGdlb21faml0dGVyKHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHNlZWQgPSAxKSkgKwogI2dndGl0bGUoIlNpZ25pZmljYW50IEdlbmVyYSIpICsKICB4bGFiKGJxdW90ZShiZXRhfiIgQ29lZmZpY2llbnQiKSkgKyAKICB5bGFiKGJxdW90ZSgiLWxvZyJbMTBdfiIoUCB2YWx1ZSkiKSkgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSsKICAjc2NhbGVfeF9icmVhayhjKC0wLjYsIC0xOCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9IGJxdW90ZShhdG9wKGJldGFbIkJNRiJdfiIgQ29lZmZpY2llbnQiLGl0YWxpYygiRGlhcnJoZWEiKSkpLCAKICAgICAgICAgICAgICAgICAgICAgZ3VpZGUgPSBndWlkZV9heGlzKG4uZG9kZ2UgPSAyKSkgKwogIHRoZW1lKHRleHQgPSAKICAgICAgICAgIGVsZW1lbnRfdGV4dChzaXplID0gMTQpLCAKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMC41KSwgCiAgICAgICAgI3Bsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04LCBoanVzdCA9IDAuNSksIAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgICAgICAgICAgIGxlZ2VuZC50ZXh0ICA9IGVsZW1lbnRfdGV4dChzaXplID0gNi41KSwKICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgICAgICAgICAgICBsZWdlbmQuYm94Lmp1c3QgPSAidG9wIiwKICAgICAgICAgICAgICBsZWdlbmQuYm94Lm1hcmdpbiA9IG1hcmdpbigwLCAxLCAwLCAxKSwKICAgICAgICAgICAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuMDEsICJjbSIpKSsKICAgICAgICAgIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAxKSksCiAgICAgICAgICAgICAgIGNvbG9yID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDEpLCBucm93ID0gMzApLAogICAgICAgICAgICAgICBmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT1OVUxMKSkKcGxvdDBkCgpsaWJyYXJ5KGdncHVicikKZmlndXJlIDwtIGdnYXJyYW5nZShwbG90MGMscGxvdDBsLHBsb3QwZCwgY29tbW9uLmxlZ2VuZCA9IEZBTFNFLCBucm93cyA9IDEsIG5jb2xzID0gMywgYWxpZ24gPSAiaHYiLCBsZWdlbmQgPSAiYm90dG9tIiwgd2lkdGhzID0gYygxLDEsMSksIGhlaWdodHMgPSBjKDUwLDUwLDUwKSkgKyB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygwLDUsMCw1KSwgImNtIiksICAgICAgICAjcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgsIGhqdXN0ID0gMC41KSwgCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksCiAgICAgICAgICAgICAgbGVnZW5kLnRleHQgID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwKICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgICAgICAgICAgICBsZWdlbmQuYm94Lmp1c3QgPSAiYm90dG9tIiwKICAgICAgICAgICAgICBsZWdlbmQuYm94Lm1hcmdpbiA9IG1hcmdpbigwLCAxLCAwLCAxKSwKICAgICAgICAgICAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuMDEsImNtIikpKwogICAgICAgICAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDEpKSwKICAgICAgICAgICAgICAgY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gMSksIG5yb3cgPSAyMCksCiAgICAgICAgICAgICAgIGZpbGw9Z3VpZGVfbGVnZW5kKHRpdGxlPU5VTEwpKQoKZ2dzYXZlKAogICJCTUZ2c1Byb3RlaW5zVm9sY2Fuby5wbmciLAogIHBsb3QgPSBmaWd1cmUsCiAgZGV2aWNlID0gTlVMTCwKICBwYXRoID0gTlVMTCwKICBzY2FsZSA9IDIuNSwKICB3aWR0aCA9IE5BLAogIGhlaWdodCA9IE5BLAogIHVuaXRzID0gYygiaW4iLCAiY20iLCAibW0iLCAicHgiKSwKICBkcGkgPSAzMDAsCiAgbGltaXRzaXplID0gVFJVRSwKICBiZyA9IE5VTEwKKQoKZmlndXJlCmBgYAoKCmBgYHtyfQojUGxvdHRpbmcKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkoZ2dwcmlzbSkKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkobWFncml0dHIpCmxpYnJhcnkoZ2diZWVzd2FybSkKbGlicmFyeShkYXRhLnRhYmxlKQpjb21wYXJpc29ucyA9IGxpc3QoYygiTG93IE5vcm1hbCIsIkhpZ2ggTm9ybWFsIiksYygiRGlhcnJoZWEiLCJIaWdoIE5vcm1hbCIpKQoKc2lnX2xvd1snYm93ZWwnXSA8LSByZXAoJ0xvdyBOb3JtYWwnLDEpCnNpZ19kaWFycmhlYVsnYm93ZWwnXSAgPC0gcmVwKCdEaWFycmhlYScsMjUpCmJvdW5kIDwtIHJiaW5kKHNpZ19sb3csc2lnX2RpYXJyaGVhKQphIDwtIGZ1bGxbLG5hbWVzKGZ1bGwpICVpbiUgYm91bmRbJ25hbWUnXVtbMV1dXQpzZXRjb2xvcmRlcihhLGJvdW5kWyduYW1lJ11bWzFdXSkKbmFtZXMoYSkgPC0gYm91bmRbJ2dlbmVfbmFtZSddW1sxXV0KYmlvY2hlbWlzdHJ5IDwtIGNiaW5kKGZ1bGxbLDE6Nl0sYSkKbmFtZXMoYmlvY2hlbWlzdHJ5KVsxMV0gPC0gJ1RORlJTRjExQiAoMm5kIEluc3RhbmNlKScKYmlvY2hlbWlzdHJ5JGJvd2VsIDwtIGZhY3RvcihiaW9jaGVtaXN0cnkkYm93ZWwsIGxldmVscz1jKDEsMiwzLDQpLCBsYWJlbHMgPSBjKCJDb25zdGlwYXRpb24iLCJMb3cgTm9ybWFsIiwiSGlnaCBOb3JtYWwiLCJEaWFycmhlYSIpKQpiaW9jaGVtaXN0cnkkYm93ZWwgPC0gZmFjdG9yKGJpb2NoZW1pc3RyeSRib3dlbCwgbGV2ZWxzPWMoIkNvbnN0aXBhdGlvbiIsIkxvdyBOb3JtYWwiLCJIaWdoIE5vcm1hbCIsIkRpYXJyaGVhIiksIGxhYmVscyA9IGMoIkNvbnN0aXBhdGlvbiIsIkxvdyBOb3JtYWwiLCJIaWdoIE5vcm1hbCIsIkRpYXJyaGVhIikpCgoKc2lnID0gZnVuY3Rpb24oeCl7CiAgaWYoeCA8IDAuMDAxKXsiKioqIn0gCiAgZWxzZSBpZih4IDwgMC4wMSl7IioqIn0KICBlbHNlIGlmKHggPCAwLjA1KXsiKiJ9CiAgZWxzZXtOQX19Cgp0ZXN0ID0gZnVuY3Rpb24oeCx5LHosaikgewogIHggPSBOVUxMCiAgeSA9IE5VTEwKICBpZiAoY291bnRlciA9PSAxKSB7CiAgICB6ID0gY29tcGFyaXNvbnNbWzFdXVsxXQogIH0gZWxzZSB7CiAgICB6ID0gY29tcGFyaXNvbnNbWzJdXVsxXQogICAgY291bnRlcjw8LTAKICB9CiAgcHJpbnQoaikKICBpZiAoc3RyX2RldGVjdCh6LCJEaWFycmhlYSIpICYgYW55KHNpZ19kaWFycmhlYVssJ2dlbmVfbmFtZSddPT1qKSkgewogICAgcmVzdWx0cyA9IGxpc3QocC52YWx1ZSA9IHNpZ19kaWFycmhlYVt3aGljaChzaWdfZGlhcnJoZWFbLCdnZW5lX25hbWUnXT09aiksXVsnYWRqLlAuVmFsJ11bWzFdXSkKICB9IGVsc2UgaWYgKHN0cl9kZXRlY3QoeiwiTG93IE5vcm1hbCIpICYgYW55KHNpZ19sb3dbLCdnZW5lX25hbWUnXT09aikpIHsKICAgIHJlc3VsdHMgPSBsaXN0KHAudmFsdWUgPSBzaWdfbG93W3doaWNoKHNpZ19sb3dbLCdnZW5lX25hbWUnXT09aiksXVsnYWRqLlAuVmFsJ11bWzFdXSkKICB9IGVsc2UgewogICAgcmVzdWx0cyA9IGxpc3QocC52YWx1ZSA9IDEpCiAgfQogIG5hbWVzKHJlc3VsdHMpIDwtICdwLnZhbHVlJwogIGNvdW50ZXIgPDwtY291bnRlcisxCiAgcmV0dXJuKHJlc3VsdHMpCn0KCmNvdW50ZXIgPDwtMQpteXBsb3RzIDwtIGxpc3QoKSAgIyBuZXcgZW1wdHkgbGlzdAogIGZvciAoaW5kIGluIDE6KG5jb2woYmlvY2hlbWlzdHJ5KS02KSkgewogIG15cGxvdHNbW2luZF1dIDwtIGxvY2FsKHsKICAgIGxhYmVsID0gcGFzdGUobmFtZXMoYmlvY2hlbWlzdHJ5KVtpbmQrNl0sc2VwPSIiKQogICAgc3ViID0gaWZlbHNlKGxhYmVsIT0nVE5GUlNGMTFCICgybmQgSW5zdGFuY2UpJyxwYXN0ZShib3VuZFsnZ2VuZV9kZXNjcmlwdGlvbiddW3doaWNoKGJvdW5kWydnZW5lX25hbWUnXT09bGFiZWwpLF0pLHBhc3RlKGJvdW5kWydnZW5lX2Rlc2NyaXB0aW9uJ11bd2hpY2goYm91bmRbJ2dlbmVfbmFtZSddPT0nVE5GUlNGMTFCJyksXSkpCiAgICBwcmludChsYWJlbCkKICAgIHByaW50KHN1YikKICAgIG4gPSAyCiAgICBwbG90bGltX2xvd2VyID0gbWluKGJpb2NoZW1pc3RyeVshaXMubmEoYmlvY2hlbWlzdHJ5WyxpbmQrNl0pLF1bLGluZCs2XSkKICAgIHBsb3RsaW1fdXBwZXIgPSBtYXgoYmlvY2hlbWlzdHJ5WyFpcy5uYShiaW9jaGVtaXN0cnlbLGluZCs2XSksXVssaW5kKzZdKQogICAgcGxvdGxpbV9iYXIgPSBwbG90bGltX2xvd2VyIC0gbgogICAgcGxvdGxpbV9tYXJnaW4gPSBhYnMocGxvdGxpbV9iYXIgLSBuKjEwKQogICAgc3VibGFiZWwgPC0gJ1RORlJTRjExQicKICAgIHBsdCA8LSBnZ3Bsb3QoZGF0YSA9IGJpb2NoZW1pc3RyeSwgYWVzKHggPSBib3dlbCwgeSA9IC5kYXRhW1tsYWJlbF1dLCBncm91cCA9IGJvd2VsKSkgKwogICAgc2NhbGVfeF9kaXNjcmV0ZShndWlkZSA9IGd1aWRlX2F4aXMobi5kb2RnZSA9IDIpKSsKICAgIGdlb21fYmVlc3dhcm0oYWVzKGNvbG9yID0gYm93ZWwpLCBzaXplID0gMC4xLCBjZXggPSAwLjUpICsKICAgIGdlb21fYm94cGxvdChhbHBoYT0wLjAsb3V0bGllci5zaGFwZSA9IE5BKSArCiAgICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA5KSkgKwogICAgZ2d0aXRsZShsYWJlbCA9IHN0cl93cmFwKGxhYmVsLCB3aWR0aCA9IDIpLHN1YnRpdGxlPXN0cl93cmFwKHN1Yix3aWR0aD0yMCkpICsKICAgIGNvb3JkX2NhcnRlc2lhbih5bGltPWMocGxvdGxpbV9sb3dlcixwbG90bGltX3VwcGVyKSxjbGlwPSJvZmYiKSsKICAgIGdlb21fc2lnbmlmKGNvbXBhcmlzb25zID0gY29tcGFyaXNvbnMsIG1hcF9zaWduaWZfbGV2ZWwgPSBzaWcsIHRlc3QgPSAndGVzdCcsIHRlc3QuYXJncyA9IGxpc3QoeiA9IGNvbXBhcmlzb25zLCBqID0gaWZlbHNlKGxhYmVsIT0nVE5GUlNGMTFCICgybmQgSW5zdGFuY2UpJyxsYWJlbCxzdWJsYWJlbCkpLCAKICAgICAgICAgICAgICAgIHlfcG9zaXRpb24gPSBwbG90bGltX2JhciwgCiAgICAgICAgICAgICAgICBzdGVwX2luY3JlYXNlID0gMC4xMCwgIHNpemUgPSAwLjUsIAogICAgICAgICAgICAgICAgdGV4dHNpemUgPSAxLjUsCiAgICAgICAgICAgICAgICB0aXBfbGVuZ3RoID0gYygwLDApKSArCiAgICBsYWJzKGNvbG9yID0gIkJNRiBDYXRlZ29yeSIsIHkgPSBpZmVsc2UoKGluZCA9PSAxIHwgaW5kID09IDYgfCBpbmQgPT0gMTEgfCBpbmQgPT0gMTYgfCBpbmQgPT0gMjEgfCBpbmQgPT0gMjYpLCJQcm90ZWluIExldmVsIiwiIikpKwogICAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9NyksIHRpdGxlLnBvc2l0aW9uID0gJ2xlZnQnLCBucm93ID0gMSwgbmNvbCA9IDQpKSArCiAgICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygwLDAscGxvdGxpbV9tYXJnaW4sMCksICJwdCIpLCAgCiAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9NS43NSksIAogICAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTQuNSksIAogICAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTApLAogICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT03KSwKICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9NyksIAogICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemU9NyksCiAgICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBhc3BlY3QucmF0aW8gPSAwLjk1KSsKICAgIHNjYWxlX2ZpbGxfbWFudWFsKGxpbWl0cyA9IGMoIkNvbnN0aXBhdGlvbiIsIkxvdyBOb3JtYWwiLCJIaWdoIE5vcm1hbCIsIkRpYXJyaGVhIiksIGxhYmVscyA9IGMoIkNvbnN0aXBhdGlvbiIsIkxvdyBOb3JtYWwiLCJIaWdoIE5vcm1hbCIsIkRpYXJyaGVhIiksIHZhbHVlcyA9IGNvbG9ycygpLAogICAgICAgICAgICAgICAgICAgIGRyb3AgPSBGQUxTRSkKICBwcmludChwbHQpCiAgfSkKfQoKYGBgCgoKYGBge3J9CmxpYnJhcnkocjJzeW1ib2xzKQpjb3VudGVyPDwtIDEKZmlndXJlMSA8LSBnZ2FycmFuZ2UocGxvdGxpc3QgPSBteXBsb3RzWzE6MTBdLCBsYWJlbHMgPSBjKExFVFRFUlNbMToxMF0pLCBsZWdlbmQgPSAidG9wIiwgYWxpZ24gPSAiaHYiLCBmb250LmxhYmVsID0gbGlzdChzaXplID0gOS41KSwgY29tbW9uLmxlZ2VuZCA9IFRSVUUsIG5yb3cgPSAyLCBuY29sID0gNSwgbGVnZW5kLmdyb2IgPSBnZXRfbGVnZW5kKG15cGxvdHNbWzJdXSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKZmlndXJlMQoKY291bnRlciA8PC0gMQpmaWd1cmUyIDwtIGdnYXJyYW5nZShwbG90bGlzdCA9IG15cGxvdHNbMTE6MjBdLCBsYWJlbHMgPSBjKExFVFRFUlNbMTE6MjBdKSwgZm9udC5sYWJlbCA9IGxpc3Qoc2l6ZSA9IDkuNSksIGxlZ2VuZCA9ICJub25lIiwgYWxpZ24gPSAiaHYiLCBucm93ID0gMiwgbmNvbCA9IDUpCgoKZmlndXJlMgoKCmNvdW50ZXIgPDwtIDEKZmlndXJlMyA8LSBnZ2FycmFuZ2UocGxvdGxpc3QgPSBteXBsb3RzWzIxOjI2XSwgbGFiZWxzID0gYyhMRVRURVJTWzIxOjI2XSksIGZvbnQubGFiZWwgPSBsaXN0KHNpemUgPSA5LjUpLCBsZWdlbmQgPSAibm9uZSIsIGFsaWduID0gImh2IiwgbnJvdyA9IDIsIG5jb2wgPSA1KQoKZmlndXJlMwpgYGAKCgpgYGB7cn0KI01haW4gVGV4dCBGaWd1cmVzCmNvdW50ZXIgPDwtIDEKZmlndXJlX21haW4xIDwtIGdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QoZmlndXJlMSxmaWd1cmUyLGZpZ3VyZTMpLCBsZWdlbmQgPSAidG9wIiwgYWxpZ24gPSAiaHYiLCBjb21tb24ubGVnZW5kID0gVFJVRSwgbnJvdyA9IDMsIG5jb2wgPSAxKQpmaWd1cmVfbWFpbjEKYGBgCgoKYGBge3J9CmNvdW50ZXIgPDwtIDEKZ2dzYXZlKAogICJCTUZ2c1Byb3RlaW5zMS5wbmciLAogIHBsb3QgPSBmaWd1cmUxLAogIGRldmljZSA9IE5VTEwsCiAgcGF0aCA9IE5VTEwsCiAgc2NhbGUgPSAxLjUsCiAgd2lkdGggPSBOQSwKICBoZWlnaHQgPSBOQSwKICB1bml0cyA9IGMoImluIiwgImNtIiwgIm1tIiwgInB4IiksCiAgZHBpID0gMzAwLAogIGxpbWl0c2l6ZSA9IFRSVUUsCiAgYmcgPSBOVUxMCikKY291bnRlciA8PC0gMQpnZ3NhdmUoCiAgIkJNRnZzUHJvdGVpbnMyLnBuZyIsCiAgcGxvdCA9IGZpZ3VyZTIsCiAgZGV2aWNlID0gTlVMTCwKICBwYXRoID0gTlVMTCwKICBzY2FsZSA9IDEuNSwKICB3aWR0aCA9IE5BLAogIGhlaWdodCA9IE5BLAogIHVuaXRzID0gYygiaW4iLCAiY20iLCAibW0iLCAicHgiKSwKICBkcGkgPSAzMDAsCiAgbGltaXRzaXplID0gVFJVRSwKICBiZyA9IE5VTEwKKQpjb3VudGVyIDw8LSAxCmdnc2F2ZSgKICAiQk1GdnNQcm90ZWluczMucG5nIiwKICBwbG90ID0gZmlndXJlMywKICBkZXZpY2UgPSBOVUxMLAogIHBhdGggPSBOVUxMLAogIHNjYWxlID0gMS41LAogIHdpZHRoID0gTkEsCiAgaGVpZ2h0ID0gTkEsCiAgdW5pdHMgPSBjKCJpbiIsICJjbSIsICJtbSIsICJweCIpLAogIGRwaSA9IDMwMCwKICBsaW1pdHNpemUgPSBUUlVFLAogIGJnID0gTlVMTAopCmNvdW50ZXIgPDwtIDEKZ2dzYXZlKAogICJCTUZ2c1Byb3RlaW5zTWFpbi5wbmciLAogIHBsb3QgPSBmaWd1cmVfbWFpbjEsCiAgZGV2aWNlID0gTlVMTCwKICBwYXRoID0gTlVMTCwKICBzY2FsZSA9IDEwMCwKICB3aWR0aCA9IE5BLAogIGhlaWdodCA9IE5BLAogIHVuaXRzID0gYygiaW4iLCAiY20iLCAibW0iLCAicHgiKSwKICBkcGkgPSAzMDAsCiAgbGltaXRzaXplID0gVFJVRSwKICBiZyA9IE5VTEwKKQpgYGAKCgoKQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkN0cmwrQWx0K0kqLgoKV2hlbiB5b3Ugc2F2ZSB0aGUgbm90ZWJvb2ssIGFuIEhUTUwgZmlsZSBjb250YWluaW5nIHRoZSBjb2RlIGFuZCBvdXRwdXQgd2lsbCBiZSBzYXZlZCBhbG9uZ3NpZGUgaXQgKGNsaWNrIHRoZSAqUHJldmlldyogYnV0dG9uIG9yIHByZXNzICpDdHJsK1NoaWZ0K0sqIHRvIHByZXZpZXcgdGhlIEhUTUwgZmlsZSkuCgpUaGUgcHJldmlldyBzaG93cyB5b3UgYSByZW5kZXJlZCBIVE1MIGNvcHkgb2YgdGhlIGNvbnRlbnRzIG9mIHRoZSBlZGl0b3IuIENvbnNlcXVlbnRseSwgdW5saWtlICpLbml0KiwgKlByZXZpZXcqIGRvZXMgbm90IHJ1biBhbnkgUiBjb2RlIGNodW5rcy4gSW5zdGVhZCwgdGhlIG91dHB1dCBvZiB0aGUgY2h1bmsgd2hlbiBpdCB3YXMgbGFzdCBydW4gaW4gdGhlIGVkaXRvciBpcyBkaXNwbGF5ZWQuCg==